为什么不将CORS标头添加到OPTIONS路由允许浏览器访问我的API?

本文翻译自:Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?

I am trying to support CORS in my Node.js application that uses the Express.js web framework. 我正在尝试在使用Express.js Web框架的Node.js应用程序中支持CORS。 I have read a Google group discussion about how to handle this, and read a few articles about how CORS works. 我已经阅读有关如何处理此问题的Google小组讨论 ,并阅读了一些有关CORS工作原理的文章。 First, I did this (code is written in CoffeeScript syntax): 首先,我做到了(代码是用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'
  # ...

It doesn't seem to work. 它似乎不起作用。 It seems like my browser (Chrome) is not sending the initial OPTIONS request. 看来我的浏览器(Chrome)没有发送初始的OPTIONS请求。 When I just updated the block for the resource I need to submit a cross-origin GET request to: 当我刚刚更新资源块时,我需要向以下站点提交跨域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'
  # ...

It works (in Chrome). 它可以工作(在Chrome中)。 This also works in Safari. 这也适用于Safari。

I have read that... 我读过...

In a browser implementing CORS, each cross-origin GET or POST request is preceded by an OPTIONS request that checks whether the GET or POST is OK. 在实现CORS的浏览器中,每个跨域的GET或POST请求之前都有一个OPTIONS请求,该请求检查GET或POST是否正常。

So my main question is, how come this doesn't seem to happen in my case? 所以我的主要问题是,在我看来,这种情况怎么似乎没有发生? Why isn't my app.options block called? 为什么不调用我的app.options块? Why do I need to set the headers in my main app.get block? 为什么需要在主app.get块中设置标题?


#1楼

参考:https://stackoom.com/question/TehS/为什么不将CORS标头添加到OPTIONS路由允许浏览器访问我的API


#2楼

I have made a more complete middleware suitable for express or connect. 我做了一个更完整的中间件,适合表达或连接。 It supports OPTIONS requests for preflight checking. 它支持OPTIONS请求进行飞行前检查。 Note that it will allow CORS access to anything, you might want to put in some checks if you want to limit access. 请注意,它将允许CORS访问任何内容,如果您想限制访问,则可能需要进行一些检查。

app.use(function(req, res, next) {
    var oneof = false;
    if(req.headers.origin) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        oneof = true;
    }
    if(req.headers['access-control-request-method']) {
        res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
        oneof = true;
    }
    if(req.headers['access-control-request-headers']) {
        res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
        oneof = true;
    }
    if(oneof) {
        res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
    }

    // intercept OPTIONS method
    if (oneof && req.method == 'OPTIONS') {
        res.send(200);
    }
    else {
        next();
    }
});

#3楼

I found the easiest way is to use the node.js package cors . 我发现最简单的方法是使用node.js包cors The simplest usage is: 最简单的用法是:

var cors = require('cors')

var app = express()
app.use(cors())

There are, of course many ways to configure the behaviour to your needs; 当然,有很多方法可以根据您的需要配置行为。 the page linked above shows a number of examples. 上面链接的页面显示了许多示例。


#4楼

My simplest solution with Express 4.2.0 (EDIT: Doesn't seem to work in 4.3.0) was: 我最简单的Express 4.2.0解决方案(编辑:在4.3.0中似乎不起作用)是:

function supportCrossOriginScript(req, res, next) {
    res.status(200);
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Content-Type");

    // res.header("Access-Control-Allow-Headers", "Origin");
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // res.header("Access-Control-Allow-Methods","POST, OPTIONS");
    // res.header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT, HEAD");
    // res.header("Access-Control-Max-Age","1728000");
    next();
}

// Support CORS
app.options('/result', supportCrossOriginScript);

app.post('/result', supportCrossOriginScript, function(req, res) {
    res.send('received');
    // do stuff with req
});

I suppose doing app.all('/result', ...) would work too... app.all('/result', ...)也可以...


#5楼

Testing done with express + node + ionic running in differente ports. 使用在不同端口中运行的express + node + ionic完成的测试。

Localhost:8100

Localhost:5000

// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests

app.all('*', function(req, res, next) {
       res.header("Access-Control-Allow-Origin", "*");
       res.header("Access-Control-Allow-Headers", "X-Requested-With");
       res.header('Access-Control-Allow-Headers', 'Content-Type');
       next();
});

#6楼

This works for me, as its an easy implementation inside the routes, im using meanjs and its working fine, safari, chrome, etc. 这对我来说很有效,因为它在路由中很容易实现,即时通讯使用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);

    });
发布了0 篇原创文章 · 获赞 52 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/CHCH998/article/details/105601369
今日推荐