在我的 angular2 应用程序中,我尝试进行跨域 ajax 调用。尽管调用成功,但在 angular2 端,总是触发错误回调而不是成功回调。这是代码:
this.http.post('http://localhost:3000/tasks/add', '["' + task + '"]', {headers: headers}).subscribe(
data => null,
err => alert("err"),
() => alert("succ")
);
在浏览器控制台中我看到了这个:
XMLHttpRequest cannot load http://localhost:3000/tasks/add. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
服务器端是在nodejs中实现的,它包含以下内容来处理预检
router.options('/add', (req, res, next) => {
console.log('!OPTIONS');
var headers = {};
// IE8 does not allow domains to be specified, just the *
// headers["Access-Control-Allow-Origin"] = req.headers.origin;
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
res.writeHead(200, headers);
res.end();
});
上述服务器代码已成功执行,客户端在预检选项请求后确实发送了 post 请求。
我的问题是,我可以在 angular2 中做什么来使其触发成功回调(它应该这样做)?
更新:
我在这里附上一张屏幕截图,它是在 Chrome 中拍摄的。它的底部显示 CORS 错误消息,但顶部显示请求正常,值为 200。事实上,它确实通过了,因为我在服务器端收到了选项和发布请求。
更新2:
在nodejs(服务器)端尝试了express-cors,仍然一样。 (我的初始代码已经处理预检选项请求 - 该代码可以在本文的原始部分中找到。除非我的原始 Nodejs 代码中有错误,否则 Express-cors 不会改变任何内容。)
下面是我用express-cors尝试的代码,与它的npm页面上的代码基本相同:
var express = require('express');
var cors = require('express-cors')
var router = express.Router();
router.use(cors({
allowedOrigins: [
'*'
]
}))
更新3:
谜团解开了!在我的原始代码中,我只在选项响应中设置 CORS header ,而不是对选项请求后面的 post 请求的响应。这似乎仍然允许整个过程在应用程序级别完成 - 因为服务器端确实收到了发布请求并处理了数据,但 Angular 看到了一个错误,因为响应不包含正确的 header 。我修改了代码,不仅在选项响应中发回 CORS header ,而且还在后响应中发回,现在 Angular 触发了成功回调。
最佳答案
事实上,Express 有一个专门用于 CORS 的模块,称为 cors
。您可以像这样安装它:npm install cors
。
也就是说,浏览器中无需执行任何操作,因为所有操作都是在跨域请求的幕后完成的:
- 浏览器发送
Origin
header - 使用简单或预检请求
- 检查 CORS 响应 header 以查看您的请求是否可以执行
此链接可以帮助您了解 CORS 在浏览器中的工作原理:http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
简而言之,这是服务器问题,而不是 Angular 应用程序中的问题。您可以在 Chrome 开发工具的“网络”选项卡中检查响应内容( header ),以查看响应中是否存在 CORS header (简单的 header 和预检 header )。
关于ajax - 如何使 angular2 在成功的预检请求后正确触发正确的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34540061/