带有 Express.js 和 jQuery.ajax 的 CORS

Posted

技术标签:

【中文标题】带有 Express.js 和 jQuery.ajax 的 CORS【英文标题】:CORS with Express.js and jQuery.ajax 【发布时间】:2012-07-28 16:38:17 【问题描述】:

我将 express.js 用于我的服务器,带有以下标头:

x-powered-by: Express
connection: keep-alive
content-length: 2
content-type: application/json; charset=utf-8
access-control-allow-methods: GET,PUT,POST,DELETE
access-control-allow-origin: *
access-control-allow-headers: x-requested-with

我打电话给res.header 允许CORS:

res.header("Access-Control-Allow-Origin:", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");  
res.header("Access-Control-Allow-Headers", "x-requested-with");

你可以在这里测试:http://my-api.rs.af.cm/api/products

对于我的前端,我使用 jsbin 并使用 $.ajax 调用我的服务器:http://jsbin.com/apizez/37/edit

这里的结果:http://jsbin.com/apizez/37

你可以看看JS控制台,你会看到这个错误:

XMLHttpRequest cannot load http://my-api.rs.af.cm/api/products. Origin http://jsbin.com is not allowed by Access-Control-Allow-Origin.

我阅读了关于 CORS 的所有其他答案,我不想使用 easyXDM。

【问题讨论】:

您的所有请求是否都将这些标头传回?您是否支持 Preflight OPTIONS 请求? 刚刚看了看,是的,Chrome 正在执行一个预检 OPTIONS 请求,该请求没有返回任何 CORS 标头。修复你会舔这个的问题。 请看developer.mozilla.org/En/… 我在 OPTIONS 请求中添加了标头,并将 "Access-Control-Allow-Headers" 设置为 "content-Type,x-requested-with,origin,accept"。但它仍然无法正常工作,您可以在我的帖子中的示例中看到。 在 Chrome javascript 控制台中,有OPTIONS http://my-api.jit.su/api/products 200 (OK),但显示为错误。 【参考方案1】:

感谢 Ryan Olds 帮助我了解 CORS 请求的工作原理。

这里是正确的标题:

res.header('Access-Control-Allow-Origin', req.headers.origin || "*");
res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'content-Type,x-requested-with');

我的所有请求在其响应中都有该标头。

我将$.getJSON 用于 jQuery 的 GET 请求,否则它不起作用。

您可以在此处查看示例: http://jsbin.com/uwevuc/2/edit

http://jsbin.com/uwevuc/2

【讨论】:

请注意,* 在大多数情况下都不起作用(有关详细信息,请检查规范中的简单与预检请求),您需要在 allow-origin 标头中明确提及您的域。此外,不需要允许 OPTIONS 也不需要像 content-type 或 origin 这样的标准标头,默认情况下是允许的。 我编辑了我的帖子以明确添加原始请求,谢谢。对于标头,我需要指定“内容类型”,否则我会出现此错误:Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 但实际上,我们不需要来源和接受。 确实如此,content-type 只能用于某些标准类型,例如 text/plain。【参考方案2】:

您还必须考虑您的预检请求。我建议您在项目中添加“cors”npm 包,并使用以下配置启动它:

const cors = require('cors');

app.use(cors(
    credentials: true,
    preflightContinue: true,
    methods: ['GET', 'POST', 'PUT', 'PATCH , 'DELETE', 'OPTIONS'],
    origin: true
);

这将为使用所列方法的任何地址启用跨域请求。 origin 参数非常灵活,您可以分隔一组地址,所有地址或通过正则表达式,例如。这是包文档:

https://expressjs.com/en/resources/middleware/cors.html

【讨论】:

以上是关于带有 Express.js 和 jQuery.ajax 的 CORS的主要内容,如果未能解决你的问题,请参考以下文章

带有 Express js 的 Angular 2 cli

每个循环都带有 express js 的节点

带有 Express(JS) 的后端 - GraphQL 变异函数不起作用

在带有 Node 和 Express 的 IE10 中使用 CORS 的安全错误

Docker - 为啥这个 express.js 容器带有暴露/发布的端口拒绝连接? (使用 boot2docker)

Express.js 虚拟主机子域设置