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 做出反应。

版本:

错误: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 });