ChatGPT解决这个技术问题 Extra ChatGPT

CORS - 如何“预检”httprequest?

我正在尝试向 WCF 服务(我拥有的)发出跨域 HTTP 请求。我已经阅读了几种处理跨域脚本限制的技术。因为我的服务必须同时满足 GET 和 POST 请求,所以我无法实现一些动态脚本标记,其 src 是 GET 请求的 URL。由于我可以自由地在服务器上进行更改,因此我开始尝试实施一种解决方法,该解决方法涉及配置服务器响应以包含“Access-Control-Allow-Origin”标头和“预检”请求以及 OPTIONS 请求。我从这篇文章中得到了这个想法:Getting CORS working

在服务器端,我的 Web 方法是在 HTTP 响应中添加“Access-Control-Allow-Origin: *”。我可以看到响应现在确实包含此标头。我的问题是:我如何“预检”请求(选项)?我正在使用 jQuery.getJSON 发出 GET 请求,但浏览器立即取消了请求,并发出了臭名昭著的问题:

Access-Control-Allow-Origin 不允许来源 http://localhost

有人熟悉这种 CORS 技术吗?客户需要进行哪些更改才能预检我的请求?

谢谢!


m
monsur

在预检请求期间,您应该看到以下两个标头:Access-Control-Request-Method 和 Access-Control-Request-Headers。这些请求标头正在向服务器请求发出实际请求的权限。您的预检响应需要确认这些标头才能使实际请求生效。

例如,假设浏览器发出带有以下标头的请求:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

然后,您的服务器应使用以下标头进行响应:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

请特别注意 Access-Control-Allow-Headers 响应标头。这个header的值应该和Access-Control-Request-Headers请求头中的headers一样,不能是'*'。

一旦您将此响应发送到预检请求,浏览器就会发出实际请求。您可以在此处了解有关 CORS 的更多信息:http://www.html5rocks.com/en/tutorials/cors/


您可以将多个域添加到 Access-Control-Allow-Origin 吗?
@botbot 您现在可能已经解决了这个问题,但如果其他人想知道可以这样做Access-Control-Allow-Origin: *
我可能错过了什么。那么我应该发送两个 XMLHttp 请求吗?一个用于预检;检查成功的响应,然后发送实际的查询?
@Kangkan 您无需担心发送预检请求。如果请求需要预检,浏览器会为您发送。
感谢您的“特别注意”位...解决了我的 node/expressjs 问题我能够添加一个过滤器来捕获这些预检请求//cors and preflight filtering app.all('*', function(req, res, next){.. //preflight needs to return exact request-header res.set('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); if ('OPTIONS' == req.method) return res.send(204);next(); });
F
Fabien Haddadi

尽管此线程可以追溯到 2014 年,但对于我们许多人来说,这个问题仍然是当前的。以下是我在 jQuery 1.12 /PHP 5.6 上下文中的处理方式:

jQuery 仅使用有限的标头发送其 XHR 请求;只发送了“起源”。

不需要预检请求。

服务器只需检测到这样的请求,并添加 "Access-Control-Allow-Origin:" 。 $_SERVER['HTTP_ORIGIN'] 标头,在检测到这是一个跨域 XHR 之后。

PHP 代码示例:

if (!empty($_SERVER['HTTP_ORIGIN'])) {
    // Uh oh, this XHR comes from outer space...
    // Use this opportunity to filter out referers that shouldn't be allowed to see this request
    if (!preg_match('@\.partner\.domain\.net$@'))
        die("End of the road if you're not my business partner.");

    // otherwise oblige
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
    // local request, no need to send a specific header for CORS
}

特别是不要添加 exit;,因为不需要预检。


n
nima

通过这些简单的步骤在 Node.js 中编写自定义中间件来解决 CORS 问题。

don't need to set anything from the client, just a little change on the Node.js server will fix the problem.

创建中间件:

// in middleware/corsResolver.js

function corsResolver(req, res, next) {
    // Website you wish to allow to connect
    // running front-end application on port 3000
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); 
    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Authorization');
    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
}

module.exports = corsResolver;

现在编辑你的 server.js(index.js 或任何启动你的节点服务器的主文件)并添加这个中间件:

// server.js or indes.js 

const corsResolver = require('path/to/resolver-middleware')

app.use(corsResolver)  // -----------> applied middleware here


// other stuff

但这不是对 CORS 预检的响应,因为它总是将这些标头添加到任何响应中。