如何配置以处理连接到 ganache 的 web3 中的 CORS 错误

How to configure to handle CORS errors in web3 connecting to ganache

我有一个 React 项目,我是 运行,位于 http:\localhost:3000,它连接到位于 http:\localhost:7545 的 ganache 运行。

我在 ganache 上部署了一个小型智能合约,它会增加一个计数器并发出一个事件,就像这样...

// SPDX-License-Identifier: MIT
pragma solidity >0.8.0;
contract Pong {
    uint public pong_count;
    function ping() public returns (uint){
        pong_count++;
        emit Pinged(this, pong_count);
        return pong_count;
    }
    event Pinged(Pong indexed me, uint count);
    function pong() public returns (uint){
        pong_count++;
        emit Ponged(this, pong_count);
        return pong_count;
    }
    event Ponged(Pong indexed me, uint count);
}

我想收听合约中的 PingedPonged 事件。

因为这只是我正在做的其他事情的帮助项目,所以我从一个 ganache 帐户中嵌入了私钥,并从中创建了一个帐户...

var pk_account = w3.eth.accounts.privateKeyToAccount(pk);

然后在我的代码的其他地方,我创建了一个名为 ponger 的 Pong 合约实例,并将其存储在我的 React 应用程序的上下文对象中,并使用 send 调用 ping() 合约方法像这样...

            ctx.ponger.methods
            .ping()
            .send({from:ctx.pk_account.address})
            .then((result,err)=>{
                if (err){
                    console.log("pong error: ", err);
                }
                else {
                    console.log("pong : ", result);
                    result.gas = 200000;
                    ctx.pk_account.signTransaction(result, sent);
                }
            });

这就像一个魅力,本地回调 sent 被正确调用。

我将事件侦听器添加到我的 ponger 实例...

function ev_Pong(ev, err){
    console.log("got pong event", ev);
}
function ev_Ping(ev, err){
    console.log("got ping event", ev);
}

ctx.ponger.events.Pinged(ev_Ping);
ctx.ponger.events.Ponged(ev_Pong);

这就是乐趣的开始。我在 ev_Ping 收到的消息是...

got ping event Error: The current provider doesn't support subscriptions: HttpProvider
    at subscription.js:176:1

所以,呃,我需要使用 websockets 而不是 HTTP,对吗?这意味着我只连接到 ws:\localhost:7545 而不是 http:\localhost:7545.

(另外:如果我使用 MetaMask 交付我的 web3,我不会遇到任何这些问题...)

但是我收到这样的 CORS 错误...

Access to XMLHttpRequest at 'ws://localhost:7545/' from origin 'http://localhost:3000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

所以我的问题是如何克服 CORS 错误?我不确定这是 ganache 问题还是老式的 CORS 问题,还是什么。

我还不想放弃事件监听和解析事件日志 - 虽然我意识到可能还有很长的路要走不同的解决方案。

我弄清楚出了什么问题,这是我的错。 web3 websocket 提供程序不强制执行 CORS,因此它可以在我的用例中使用。

我遇到的问题是,即使我更改了发送 web3 的 URI 中的协议,我仍然要求 HTTPProvider 而不是 WebsocketProvider

出于我的目的,我对 getWeb3.js 进行了一些更改...

const getWeb3 = (url) => {

...

      if (url){
        if (url.substring(0,2) === 'ws'){
          const provider = new Web3.providers.WebsocketProvider(url);
          const web3 = new Web3(provider);
          console.log("Using WS URL for web3: ", url);
          resolve(web3);  
        }
        else {
          const provider = new Web3.providers.HttpProvider(url);
          const web3 = new Web3(provider);
          console.log("Using HTTP URL for web3: ", url);
          resolve(web3);  
        }
      }

...
}

这很好用。

从好的方面来说,它让我更好地理解了 CORS。我真的不喜欢在浏览器中禁用任何东西。