成功的预检请求后,如何使angular2正确触发正确的回调

时间:2015-12-31 02:05:48

标签: ajax node.js cors angular

在我的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一致。事实上它确实经历了,因为我收到了服务器端的选项和发布请求。

enter image description here

更新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触发成功回调。

2 个答案:

答案 0 :(得分:0)

您的错误消息看起来不像预检请求成功。预检请求由浏览器在实际请求之前自动生成,如果预检请求导致错误,如您的情况,则根本不会发出实际请求。

请在服务器上尝试此操作:

 headers["Access-Control-Allow-Origin"] = "http://localhost";

答案 1 :(得分:0)

事实上,有一个名为cors的快速CORS专用模块。您可以像这样安装:npm install cors

也就是说,浏览器无关,因为所有内容都是在跨域请求的基础上完成的:

  • 浏览器发送Origin标题
  • 使用简单或预先发出的请求
  • 检查CORS响应标头以查看您的请求是否可以执行

此链接可帮助您了解CORS在浏览器中的工作原理:http://restlet.com/blog/2015/12/15/understanding-and-using-cors/

简而言之,这是一个服务器问题,而不是Angular应用程序中的问题。您可以在Chrome开发工具,标签网络中查看响应内容(标题),以查看响应中是否存在CORS标头(包括简单和预检)。