我试图在使用Express.js web框架的Node.js应用程序中支持CORS。我已经阅读了谷歌关于如何处理这个问题的小组讨论,并阅读了一些关于CORS如何工作的文章。首先,我这样做(代码是用CoffeeScript语法写的):

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

这似乎不管用。似乎我的浏览器(Chrome)没有发送最初的选项请求。当我刚刚更新了块的资源,我需要提交一个跨起源GET请求:

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

它工作(在Chrome)。这也适用于Safari。

我听说……

在实现CORS的浏览器中,每个跨源GET或POST请求之前都有一个OPTIONS请求,用于检查GET或POST是否正常。

所以我的主要问题是,为什么这种情况在我身上没有发生?为什么我的app。options块没有被调用?为什么我需要在我的主app.get块设置标题?


当前回答

如果你想让它特定于控制器,你可以使用:

res.setHeader("X-Frame-Options", "ALLOWALL");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

请注意,这也将允许iframes。

其他回答

简单很难:

 let my_data = []
const promise = new Promise(async function (resolve, reject) {
    axios.post('https://cors-anywhere.herokuapp.com/https://maps.googleapis.com/maps/api/directions/json?origin=33.69057660000001,72.9782724&destination=33.691478,%2072.978594&key=AIzaSyApzbs5QDJOnEObdSBN_Cmln5ZWxx323vA'
        , { 'Origin': 'https://localhost:3000' })
        .then(function (response) {
            console.log(`axios response ${response.data}`)
            const my_data = response.data
            resolve(my_data)
        })
        .catch(function (error) {
            console.log(error)
            alert('connection error')
        })
})
promise.then(data => {
    console.log(JSON.stringify(data))
})

我使用以下步骤我的web应用程序,我成功了:

快递添加cors包:

npm install cors --save

在bodyParser配置后添加以下行。我在bodyParser之前添加了一些麻烦:

 // enable cors to the server
const corsOpt = {
    origin: process.env.CORS_ALLOW_ORIGIN || '*', // this work well to configure origin url in the server
    methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], // to works well with web app, OPTIONS is required
    allowedHeaders: ['Content-Type', 'Authorization'] // allow json and token in the headers
};
app.use(cors(corsOpt)); // cors for all the routes of the application
app.options('*', cors(corsOpt)); // automatic cors gen for HTTP verbs in all routes, This can be redundant but I kept to be sure that will always work.

您可以使用Express中间件,阻止您的域和方法。

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", process.env.DOMAIN); // update to match the domain you will make the request from
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});

尝试将控制权传递给下一个匹配的路由。如果Express首先匹配app.get路由,那么它不会继续到options路由,除非你这样做(注意使用next):

app.get('somethingelse', function(req, res, next) {
    //..set headers etc.

    next();
});

在组织CORS的东西方面,我把它放在一个对我来说很有效的中间件中:

//CORS middleware
var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'example.com');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    next();
}

//...
app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'cool beans' }));
    app.use(express.methodOverride());
    app.use(allowCrossDomain);
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

这对我来说是有效的,因为它是一个很容易实现的路由,im使用meanjs和它的工作精细,safari, chrome等。

app.route('/footer-contact-form').post(emailer.sendFooterMail).options(function(req,res,next){ 
        res.header('Access-Control-Allow-Origin', '*'); 
        res.header('Access-Control-Allow-Methods', 'GET, POST');
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
        return res.send(200);

    });