Post请求在Postman和curl中正常,在JavaScript中报错
问题:Postman生成的JavaScript Fetch请求触发CORS错误,curl/Postman直接请求正常
我的POST请求在Postman和curl里都能正常运行,curl命令示例如下:
(base) a@DESKTOP-DGPCO9D:~/ef-firebase-functions$ curl --location --request POST 'http://127.0.0.1:5001/ef/us-central1/getNonceToSign' --header 'Content-Type: application/json' --data-raw '{ "address" : "0x874814" }' {"nonce":"8855"}(base) a@DESKTOP-DGPCO9D:~/ef-firebase-functions$
但用Postman生成的JavaScript代码调用时,却出现CORS错误和Fetch请求失败的问题。我已经尝试在fetch前添加await,但问题依然存在。有没有人遇到过类似的情况?
Postman生成的JavaScript代码如下:
var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); var raw = JSON.stringify({ address: "0x874814", }); var requestOptions = { method: "POST", headers: myHeaders, body: raw, }; await fetch( "http://127.0.0.1:5001/ef/us-central1/getNonceToSign", requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.log("error", error));
解决思路
这是典型的浏览器同源策略限制导致的问题:
- curl和Postman不属于浏览器环境,不受同源策略约束,所以能正常请求接口
- 浏览器里的Fetch请求会触发预检(OPTIONS)请求,后端如果没有配置正确的CORS响应头,就会被浏览器拦截,抛出CORS错误
针对Firebase Functions的场景,解决方法如下:
- 使用
corsnpm包快速配置
安装包后在函数中引入并包裹业务逻辑:const functions = require("firebase-functions"); const cors = require("cors")({ origin: true }); exports.getNonceToSign = functions.https.onRequest((req, res) => { cors(req, res, () => { // 你的原有业务逻辑 const address = req.body.address; res.json({ nonce: "8855" }); }); }); - 手动设置CORS响应头(无需第三方包)
exports.getNonceToSign = functions.https.onRequest((req, res) => { // 生产环境建议替换为具体域名,*表示允许所有源 res.set("Access-Control-Allow-Origin", "*"); res.set("Access-Control-Allow-Methods", "POST, OPTIONS"); res.set("Access-Control-Allow-Headers", "Content-Type"); // 处理预检OPTIONS请求 if (req.method === "OPTIONS") { res.status(204).send(""); return; } // 你的业务逻辑 const address = req.body.address; res.json({ nonce: "8855" }); });
另外,你代码中同时混用了await和.then(),可以统一风格提升可读性,比如改成全await写法:
try { const response = await fetch( "http://127.0.0.1:5001/ef/us-central1/getNonceToSign", requestOptions ); const result = await response.text(); console.log(result); } catch (error) { console.log("error", error); }
内容的提问来源于stack exchange,提问作者Potion
相关产品推荐
相关产品推荐

