You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署至Google App Engine后调用child_process触发CORS错误排查

部署Google App Engine后CORS拦截问题分析

问题描述

我搭了个Express服务器,本地运行完全正常,但部署到Google App Engine后发送请求就被CORS策略拦截。只要把exec那段代码注释掉,直接返回响应就没这个问题,这是为啥?

我的代码

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const { exec } = require('child_process');

const app = express();
app.use(bodyParser.json());
app.use(cors());
module.exports = app

app.post("/", (req,res) =>{ 
    console.log("Get from /"); 
    console.log(req.body.data)

// 注释掉这段exec就正常
    exec('npx hardhat run scripts/deploy.js --network goerli',
        (error, stdout, stderr) => {
            if (error !== null) {
                console.log(`exec error: ${error}`);
            }
            else{
              res.send("response");
            }
        })
});

app.listen(8080, () => {
  console.log('listening on port 8080');
});

package.json

{
  "name": "hardhat-project",
  "devDependencies": {
    "@nomiclabs/hardhat-ethers": "^2.0.6",
    "ethers": "^5.6.9",
    "hardhat": "^2.9.9"
  },
  "version": "1.0.0",
  "description": "smart contract",
  "main": "hardhat.config.js",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.18.1",
    "firebase-admin": "^11.0.0"
  },
  "scripts": {
    "start": "node src/index.js",
    "test": "mocha"
  },
  "author": "",
  "license": "ISC"
}

错误截图

CORS错误截图

原因分析

  1. 请求超时未响应,浏览器误判为CORS错误
    Google App Engine对请求有默认超时限制(一般60秒),而用npx hardhat run部署合约到Goerli测试网大概率会超时。exec是异步操作,还没等到回调触发返回响应,GAE就把连接掐了,浏览器收不到任何响应,就会以CORS拦截的形式报错。去掉exec直接返回,请求秒完成,自然没这个问题。

  2. 依赖未安装导致exec执行失败,无响应返回
    你的hardhat放在devDependencies里,GAE部署时默认不会安装dev依赖,导致找不到hardhat命令,exec直接报错。但你的代码只在控制台打印错误日志,没给客户端返回任何响应,请求一直挂着,浏览器就触发CORS拦截。

  3. GAE环境限制无法执行外部命令
    GAE标准环境对进程执行管得很严,可能不允许通过exec调用npx、hardhat这类外部命令。这种情况下exec直接失败,同样因为没返回响应,导致浏览器报CORS错。

解决办法

1. 把hardhat移到dependencies

修改package.json,把hardhat及其相关依赖从devDependencies挪到dependencies,确保部署时能装上:

{
  "dependencies": {
    "@nomiclabs/hardhat-ethers": "^2.0.6",
    "ethers": "^5.6.9",
    "hardhat": "^2.9.9",
    "cors": "^2.8.5",
    "express": "^4.18.1",
    "firebase-admin": "^11.0.0"
  }
}

2. 处理exec错误,确保返回响应

不管exec成功还是失败,都要给客户端返回响应,别让请求挂着:

exec('npx hardhat run scripts/deploy.js --network goerli',
    (error, stdout, stderr) => {
        if (error !== null) {
            console.log(`exec error: ${error}`);
            res.status(500).send(`部署失败: ${error.message}`);
        } else {
          res.send("部署成功");
        }
    })

3. 改用hardhat API直接部署,避免exec

别在GAE里调用外部命令,直接用Node.js代码引入hardhat API执行部署:

const hre = require("hardhat");

app.post("/", async (req,res) =>{ 
    try {
        const Contract = await hre.ethers.getContractFactory("YourContract");
        const contract = await Contract.deploy();
        await contract.deployed();
        res.send(`合约部署成功,地址: ${contract.address}`);
    } catch (error) {
        console.error(error);
        res.status(500).send(`部署失败: ${error.message}`);
    }
});

4. 调整GAE请求超时(不推荐)

如果非要保留exec,可以在app.yaml里延长超时时间(最大24小时,但合约部署不该是同步长请求):

runtime: nodejs16
handlers:
  - url: /.*
    script: auto
    timeout: 300s # 设置为5分钟

内容的提问来源于stack exchange,提问作者Nina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 04:27:16