来自angular的HTTP请求将使用方法OPTIONS而不是POST发送

时间:2016-11-08 22:18:14

标签: javascript php angularjs http cors

我试图从我的angular.js应用程序向我的服务器发送一些HTTP请求,但我需要解决一些cors错误。

HTTP请求等于此示例:

functions.test = function(foo, bar) {
    return $http({
        method: 'POST',
        url: api_endpoint + 'test',
        headers: {
            'foo': 'value',
            'content-type': 'application/json'
        },
        data: {
            bar:'value'
        }
    });
};

第一次尝试以一些cors错误结束。所以我已经在我的php服务器脚本中实现了以下几行:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type');

现在消除了第一个错误。

现在开发人员控制台(在chrome上)显示以下错误:

  

angular.js:12011 OPTIONS http://localhost:8000/test(匿名   功能)

     

423ef03a:1 XMLHttpRequest无法加载   http://localhost:8000/test。预检的响应具有无效的HTTP   状态代码400

并且网络请求看起来像我预期的那样(状态400也是预期的):

network request

我无法想象如何解决问题(以及如何理解)为什么请求将作为OPTIONS发送到localhost并作为POST发送到远程服务器。有没有解决方法如何解决这个奇怪的事情?

6 个答案:

答案 0 :(得分:8)

OPTIONS请求称为pre-flight request,是Cross-origin resource sharing (CORS)的一部分。浏览器使用它来检查是否允许来自特定域的真实请求(如果成功的话)。这意味着,如果浏览器收到对HTTP 200 OK请求的OPTIONS响应,则会在您的情况下发送“真实”请求POST

在这些情况下,浏览器会发送飞行前请求:

  • 使用application/xmlapplication/json等自定义HTTP标头
  • 请求方法不是GETHEADPOST,而POST方法属于另一种内容类型,而不是application/x-www-form-urlencoded,{{1 }或multipart/form-data

您需要确保对 pre-flight 请求的响应具有以下属性

  • 成功的HTTP状态代码,即text/plain
  • 标题200 OK(通配符Access-Control-Allow-Origin: *允许来自任何域的请求,当然您可以使用任何特定域来限制访问)

另一方面,服务器可以拒绝CORS请求,只需通过以下属性发送对 pre-flight 请求的响应:

  • 不成功的HTTP代码(即*除外)
  • 成功的HTTP代码(例如2XX),但没有任何CORS标头(即200 OK

因此,在您的情况下,存在正确的标头,您只需确保飞行前响应的HTTP状态代码为Access-Control-Allow-*

有关详细信息,请参阅documentation on Mozilla Developer Network或举例HTML5Rocks' CORS tutorial

答案 1 :(得分:1)

就放

parent

在服务器端应用程序的开头,您应该没事。

答案 2 :(得分:0)

我遇到了一个非常类似的问题,写了一个Angular 2应用程序 - 它使用了一个NODE服务器用于API。

由于我在本地计算机上进行开发,因此当我尝试从Angular应用程序发布到API时,我一直遇到Cross Origin Header问题。

设置Headers(在节点服务器中)如下所示适用于GET请求,但我的PUT请求一直将空对象发布到数据库。

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, 
Origin, Authorization, Accept, Client-Security-Token, Accept-
Encoding, X-Auth-Token, content-type');

在阅读Dawid Ferenczy's post之后,我意识到PREFLIGHT请求正在向我的服务器发送空白数据,这就是为什么我的数据库条目为空,所以我在NODE JS服务器中添加了这一行:

  if (req.method == "OPTIONS")
    {
        res.writeHead(200, {"Content-Type": "application/json"});
        res.end();
    }

所以现在我的服务器忽略了PREFLIGHT请求,(并返回状态200,让浏览器知道所有内容都很常见......)这样,真正的请求可以通过,我将真实的数据发布到我的数据库!

答案 3 :(得分:0)

对于spring boot应用程序,要启用cors请求,请在各自的控制器上使用@CrossOrigin(origins =“ *”,maxAge = 3600)。

Refer this doc

答案 4 :(得分:0)

最好是

  1. 已设置proxy.conf.json:
    {
      "/api": {
        "target": "http://localhost:8080",
        "secure": false,
        "logLevel": "debug",
        "changeOrigin": true
      }
    } 
  1. 然后确保您用于发送请求的URL是相对(/ api / something)而不是绝对(localhost:8080 / api /某物)。因为在这种情况下,代理将无法工作。

祝你好运!

答案 5 :(得分:0)

从铬的 V79 + 下,OPTIONS检查(的预飞行请求)将不再出现在网络标签 - Source