CORS 策略的 Sails、React 和 Axios 错误:请求的资源上不存在 'Access-Control-Allow-Origin' header
Sails, React and Axios Error with CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
我真的研究过这个问题,对于 SailsJS 没有什么清楚的。我是 运行 风帆并在本地使用 npm start 做出反应。
版本:
- Sailsjs:1.4.0
- ReactJS: ^16.13.1
- Axios: ^0.19.2
- 节点:v15.0.1
错误:Access to XMLHttpRequest at 'http://localhost:1337/User/Read/2' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我真的检查了 whosebug.com 中的票证和 sails 中的文档,还测试了不同的解决方案和选项,我唯一可以使用的方法是使用 Moesif Origin & CORS Changer
中的小部件chrome,但我需要配置 headers 和产品的安全性:
https://sailsjs.com/documentation/concepts/security/cors, https://sailsjs.com/documentation/reference/configuration/sails-config-security
请求Headers:
GET /User/Read/2 HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Origin: http://localhost:3000
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
我在 security.js 中用于 cors in sails 的配置是:
module.exports.security = {
cors: {
allRoutes: true,
allowOrigins: ['http://localhost:3000'],
allowCredentials: false,
allowRequestHeaders: [
'X-Powered-By',
'Content-Type',
'Accept',
'Origin',
'Accept-Encoding',
'Accept-Language',
'Connection',
'Host',
'Origin',
'Referer',
'Sec-Fetch-Dest',
'Sec-Fetch-Mode',
'Sec-Fetch-Site',
'User-Agent',
'Pragma',
'Cache-Control',
]
},
csrf: false
};
React 中的 Axios 请求:
var axios = require('axios');
axios({
method: 'get',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'},
url: 'http://localhost:1337/User/Read/2',
}).then(function (response) {
console.log(response.data);
});
以及路由请求:
'GET /User/Read/:id': {
controller: "User",
action: "read"
},
最后我是这样解决的:
在 http.js 上,添加了请求 headers:
module.exports.http = {
middleware: {
order: [
'cookieParser',
'session',
'bodyParser',
'compress',
'poweredBy',
'appRequestLogger', // custom logger
'router',
'www',
'favicon'
],
appRequestLogger: function (req, res, next) {
const env = process.env.NODE_ENV || 'development';
sails.log.debug('<<------------------------------');
sails.log.debug('Requested data :: ');
sails.log.debug(' ', req.method, req.url);
sails.log.debug(' Headers:');
sails.log.debug(req.headers);
if (env.toLowerCase() !== 'production') {
sails.log.debug(' Params:');
sails.log.debug(req.params);
sails.log.debug(' Body:');
sails.log.debug(req.body);
}
sails.log.debug('------------------------------>>');
// This is a work around to allow CORS requests as Sails does not send these
// headers in the response to preflight/actual requests even when they are
// declared in config/security.js under CORS config
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
// Check graphql preflight request, if yes then prevent the request reaching
// the express-graphql server. Currently the express-graphql server only accepts
// GET and POST hence rejects the preflight request. CORS needs that a server
// accepts preflight requests to facilitate cross-site access. Therefore, return
// immediately with a success.
// Otherwise fall through by calling next()
if (req.method === 'OPTIONS' && req.url.indexOf('graphql') > -1) {
return res.status(200).send();
} else {
return next();
}
},
},
};
我就是这样用的
cors: {
allRoutes: true,
allowOrigins: "*",
allowCredentials: false,
allowRequestHeaders: "*",
}
确保在 allowOrigins: ['http://mywebsite.com]
生产环境中添加客户端主机
在/config/http.js文件中,取消注释'order'数组片段并添加header myRequestLogger 方法中的参数。
order: [
'startRequestTimer',
'cookieParser',
'session',
'myRequestLogger',
'bodyParser',
'handleBodyParserError',
'compress',
'methodOverride',
'poweredBy',
'$custom',
'router',
'www',
'favicon',
'404',
'500'
],
myRequestLogger: function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
return next();
},
/config/cors.js(sails v0.12)或 /config/security.js (sails v1.x) 添加以下代码片段
module.exports.security = { //sails v1.x, if is sails v0.12 change security for cors
allRoutes: true,
allowOrigins: '*',
allowCredentials: false,
allowRequestMethods: 'GET,POST,PUT,DELETE,OPTIONS,HEAD',
allowRequestHeaders: 'content-type'
}
万一 none 有效(我发现这很难发生),添加 控制器 的 return 方法(但是,我觉得没必要):
return res.set({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
}).json({ status: true, //body });
我真的研究过这个问题,对于 SailsJS 没有什么清楚的。我是 运行 风帆并在本地使用 npm start 做出反应。
版本:
- Sailsjs:1.4.0
- ReactJS: ^16.13.1
- Axios: ^0.19.2
- 节点:v15.0.1
错误:Access to XMLHttpRequest at 'http://localhost:1337/User/Read/2' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我真的检查了 whosebug.com 中的票证和 sails 中的文档,还测试了不同的解决方案和选项,我唯一可以使用的方法是使用 Moesif Origin & CORS Changer
中的小部件chrome,但我需要配置 headers 和产品的安全性:
https://sailsjs.com/documentation/concepts/security/cors, https://sailsjs.com/documentation/reference/configuration/sails-config-security
请求Headers:
GET /User/Read/2 HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Origin: http://localhost:3000
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
我在 security.js 中用于 cors in sails 的配置是:
module.exports.security = {
cors: {
allRoutes: true,
allowOrigins: ['http://localhost:3000'],
allowCredentials: false,
allowRequestHeaders: [
'X-Powered-By',
'Content-Type',
'Accept',
'Origin',
'Accept-Encoding',
'Accept-Language',
'Connection',
'Host',
'Origin',
'Referer',
'Sec-Fetch-Dest',
'Sec-Fetch-Mode',
'Sec-Fetch-Site',
'User-Agent',
'Pragma',
'Cache-Control',
]
},
csrf: false
};
React 中的 Axios 请求:
var axios = require('axios');
axios({
method: 'get',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'},
url: 'http://localhost:1337/User/Read/2',
}).then(function (response) {
console.log(response.data);
});
以及路由请求:
'GET /User/Read/:id': {
controller: "User",
action: "read"
},
最后我是这样解决的:
在 http.js 上,添加了请求 headers:
module.exports.http = {
middleware: {
order: [
'cookieParser',
'session',
'bodyParser',
'compress',
'poweredBy',
'appRequestLogger', // custom logger
'router',
'www',
'favicon'
],
appRequestLogger: function (req, res, next) {
const env = process.env.NODE_ENV || 'development';
sails.log.debug('<<------------------------------');
sails.log.debug('Requested data :: ');
sails.log.debug(' ', req.method, req.url);
sails.log.debug(' Headers:');
sails.log.debug(req.headers);
if (env.toLowerCase() !== 'production') {
sails.log.debug(' Params:');
sails.log.debug(req.params);
sails.log.debug(' Body:');
sails.log.debug(req.body);
}
sails.log.debug('------------------------------>>');
// This is a work around to allow CORS requests as Sails does not send these
// headers in the response to preflight/actual requests even when they are
// declared in config/security.js under CORS config
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
// Check graphql preflight request, if yes then prevent the request reaching
// the express-graphql server. Currently the express-graphql server only accepts
// GET and POST hence rejects the preflight request. CORS needs that a server
// accepts preflight requests to facilitate cross-site access. Therefore, return
// immediately with a success.
// Otherwise fall through by calling next()
if (req.method === 'OPTIONS' && req.url.indexOf('graphql') > -1) {
return res.status(200).send();
} else {
return next();
}
},
},
};
我就是这样用的
cors: {
allRoutes: true,
allowOrigins: "*",
allowCredentials: false,
allowRequestHeaders: "*",
}
确保在 allowOrigins: ['http://mywebsite.com]
生产环境中添加客户端主机
在/config/http.js文件中,取消注释'order'数组片段并添加header myRequestLogger 方法中的参数。
order: [
'startRequestTimer',
'cookieParser',
'session',
'myRequestLogger',
'bodyParser',
'handleBodyParserError',
'compress',
'methodOverride',
'poweredBy',
'$custom',
'router',
'www',
'favicon',
'404',
'500'
],
myRequestLogger: function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
return next();
},
/config/cors.js(sails v0.12)或 /config/security.js (sails v1.x) 添加以下代码片段
module.exports.security = { //sails v1.x, if is sails v0.12 change security for cors
allRoutes: true,
allowOrigins: '*',
allowCredentials: false,
allowRequestMethods: 'GET,POST,PUT,DELETE,OPTIONS,HEAD',
allowRequestHeaders: 'content-type'
}
万一 none 有效(我发现这很难发生),添加 控制器 的 return 方法(但是,我觉得没必要):
return res.set({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
}).json({ status: true, //body });