在我的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();
});
上述服务器代码已成功执行,客户端确实在预检选项请求后发送了帖子请求。
我的问题是,我可以在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标头,但没有在选项请求之后对post请求进行响应。这似乎仍然允许整个过程在应用程序级别完成 - 因为服务器端确实获得了post请求并处理了数据,但angular看到了一个错误,因为响应没有包含正确的头文件。我修改了我的代码,不仅在选项响应中发回CORS头,还在post响应中发送,现在angular触发成功回调。
答案 0 :(得分:0)
您的错误消息看起来不像预检请求成功。预检请求由浏览器在实际请求之前自动生成,如果预检请求导致错误,如您的情况,则根本不会发出实际请求。
请在服务器上尝试此操作:
headers["Access-Control-Allow-Origin"] = "http://localhost";
答案 1 :(得分:0)
事实上,有一个名为cors
的快速CORS专用模块。您可以像这样安装:npm install cors
。
也就是说,浏览器无关,因为所有内容都是在跨域请求的基础上完成的:
Origin
标题此链接可帮助您了解CORS在浏览器中的工作原理:http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
简而言之,这是一个服务器问题,而不是Angular应用程序中的问题。您可以在Chrome开发工具,标签网络中查看响应内容(标题),以查看响应中是否存在CORS标头(包括简单和预检)。