为避免 'Access-Control-Allow-Origin' 问题,应如何在调用位于其他地方的 API 的 MERN 应用程序上设置 CORS?
To avoid the 'Access-Control-Allow-Origin' issue, how should CORS be set up on a MERN app that calls an API that is located somewhere else?
我正在玩一个调用 themealdb api 的 MERN 应用程序,它工作正常,直到应用 JWT 和 cookie 的身份验证和授权。如果我登录,那么无论何时拨打电话,我都会收到以下内容
Access to XMLHttpRequest at
'https://www.themealdb.com/api/json/v1/1/search.php?f=a' from origin
'http://localhost:3000' has been blocked by CORS policy: The value of
the 'Access-Control-Allow-Origin' header in the response must not be
the wildcard '*' when the request's credentials mode is 'include'. The
credentials mode of requests initiated by the XMLHttpRequest is
controlled by the withCredentials attribute.
在我看来,React 端的以下代码行是罪魁祸首
axios.defaults.withCredentials = true;
如果我注释掉这一行,问题就会消失,调用也没有问题。
环顾四周的答案似乎可以在对我来说是 Express 的后端制定解决方案,但到目前为止没有任何效果。
Express 代码有这个用于 cors:
app.use(cors({origin: ['http://localhost:3000'], credentials: true}));
我用 corsOptions 的 let 和 var 将其替换为以下内容,以防出现相同的错误:
let corsOptions = {
origin: 'http://localhost:3000',
credentials : true
}
app.use(cors(corsOptions));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
有什么建议吗?对于这种情况,需要在服务器端添加什么才能使其正常工作?
谢谢
我通常使用此代码段为预配置的来源列表启用 CORS:
const allowOrigins = ['http://localhost:3000', /** other domains if any */ ]
const corsOptions = {
credentials: true,
origin: function(origin, callback) {
if (allowOrigins.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
}
server.use(cors(corsOptions));
此外,as per MDN, you can try setting the withCredentials
选项 false
在您的客户端上。
或者,如果您要连接到您不维护的服务,您可以创建一个 Node 代理来调用第三方服务,而不是您的客户端直接调用它。
const express = require('express')
const request = require('request')
const port = process.env.PORT || 8000
let server = express()
const proxyMiddleware = (req, res, next) => {
let url = `https://www.example.com/${req.url}`
let proxyRequest = request(url)
// Pass request to proxied request url
req.pipe(proxyRequest)
// Respond to the original request with the response from proxyRequest
proxyRequest.pipe(res)
}
server.use(proxyMiddleware)
server.listen(port, () => console.log(`Listening on ${port}`))
我正在玩一个调用 themealdb api 的 MERN 应用程序,它工作正常,直到应用 JWT 和 cookie 的身份验证和授权。如果我登录,那么无论何时拨打电话,我都会收到以下内容
Access to XMLHttpRequest at 'https://www.themealdb.com/api/json/v1/1/search.php?f=a' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
在我看来,React 端的以下代码行是罪魁祸首
axios.defaults.withCredentials = true;
如果我注释掉这一行,问题就会消失,调用也没有问题。
环顾四周的答案似乎可以在对我来说是 Express 的后端制定解决方案,但到目前为止没有任何效果。 Express 代码有这个用于 cors:
app.use(cors({origin: ['http://localhost:3000'], credentials: true}));
我用 corsOptions 的 let 和 var 将其替换为以下内容,以防出现相同的错误:
let corsOptions = {
origin: 'http://localhost:3000',
credentials : true
}
app.use(cors(corsOptions));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
有什么建议吗?对于这种情况,需要在服务器端添加什么才能使其正常工作?
谢谢
我通常使用此代码段为预配置的来源列表启用 CORS:
const allowOrigins = ['http://localhost:3000', /** other domains if any */ ]
const corsOptions = {
credentials: true,
origin: function(origin, callback) {
if (allowOrigins.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
}
server.use(cors(corsOptions));
此外,as per MDN, you can try setting the withCredentials
选项 false
在您的客户端上。
或者,如果您要连接到您不维护的服务,您可以创建一个 Node 代理来调用第三方服务,而不是您的客户端直接调用它。
const express = require('express')
const request = require('request')
const port = process.env.PORT || 8000
let server = express()
const proxyMiddleware = (req, res, next) => {
let url = `https://www.example.com/${req.url}`
let proxyRequest = request(url)
// Pass request to proxied request url
req.pipe(proxyRequest)
// Respond to the original request with the response from proxyRequest
proxyRequest.pipe(res)
}
server.use(proxyMiddleware)
server.listen(port, () => console.log(`Listening on ${port}`))