Angular $http 正在发送 OPTIONS 而不是 PUT/POST

Posted

技术标签:

【中文标题】Angular $http 正在发送 OPTIONS 而不是 PUT/POST【英文标题】:Angular $http is sending OPTIONS instead of PUT/POST 【发布时间】:2015-07-27 01:40:21 【问题描述】:

我正在尝试通过 php 后端在 mysql 数据库中更新/插入数据。我正在使用 AngularJS 构建前端,并使用 $http 服务与 REST API 进行通信。

我的设置如下所示:

我正在通过 $httpProvider 设置标头:

 $httpProvider.defaults.withCredentials = true;
 $httpProvider.defaults.headers = 'Content-Type': 'application/json;charset=utf-8';

POST-Call 看起来像这样:

   return $http(
      url: url,
      method: "POST",
      data: campaign
    );

Chrome 中的开发控制台向我展示了这一点:

当我从 POST 更改为 PUT 时,我发送的是 OPTIONS 调用而不是 PUT。并且内容类型只切换到content-type

我的请求负载作为对象发送:

如何正确设置标题?


编辑:

PHP 后端设置了一些标头:

   $e->getResponse()
              ->getHeaders()
              ->addHeaderLine('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

   $e->getResponse()
              ->getHeaders()
              ->addHeaderLine('Access-Control-Allow-Origin', '*');

有什么遗漏吗?

【问题讨论】:

application/json 是默认的内容类型集。如果在某处将其设置为 text/plain,则需要在代码中搜索 @Chandermani 我的代码相当小。我有一个 api.js 文件,我在其中执行此操作,还有一个 .config.js 文件,我当前在其中手动设置了标头。 我同意这个共识。不需要您的标头。一些非常奇怪的事情正在发生。我浏览了我用 Angular 编写的每个http.post,它们都很简单。标题是假定的。 【参考方案1】:

好的,我已经解决了。

出了什么问题? DELETE、PUT 和 POST 的 CORS 工作流程如下:

它的作用是:

    检查将发出哪个请求 如果是 POST、PUT 或 DELETE 它首先发送一个 OPTION 请求以检查发送请求的域是否与来自服务器的域相同。 如果不是,它希望允许一个 Access-Header 发送这个请求

此处的重要提示:OPTIONS 请求不会发送凭据

所以我的后端服务器不允许 PUT 请求。

解决方案: 将其放入.htaccess 文件中

RewriteCond %REQUEST_METHOD OPTIONS
RewriteRule ^(.*)$ blank.php [QSA,L]
Header set Access-Control-Allow-Origin "http://sub.domain:3000"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"

之后,在公共文件夹中创建一个名为 blank.php 的空 .php 文件。

编辑:正如一位评论者指出的那样,您可以将此重写规则添加到您的 .htaccess 文件中,而不是创建一个空的 PHP 文件\;

RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%HTTP:ORIGIN]]

澄清一下:

    我已经发送了 Access-Control-Header 它解决的是前两行,并且 Access-Control-Allow-Origin 来自带有端口的特定子域

我能找到的最佳网站learn more about CORS。

【讨论】:

不用创建blank.php,我们可以使用RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%HTTP:ORIGIN]] 谢谢@gruberb。您的信息帮助我理解了为什么我得到 OPTION 而不是 POST。 恭喜。我从未见过如此完整的 CORS 解释。 它通常不仅限于角度 或者你可以添加 header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding") ;到你的 php 脚本 - youtube.com/watch?v=GJAe8cZmMAs【参考方案2】:

您不需要手动指定 $http 标头,这一切都在幕后为您完成,并且它们会自动设置为 application/json 用于 POSTPUT 类型的请求。所以你应该做的就是

$http.post(url, data);
$http.put(url, data);

【讨论】:

我删除了它,但随后我发送了一个 OPTIONS 调用而不是一个 PUT/POST。如果我设置它们,至少我会发出正确的呼叫。 @gruberb,你应该尝试阅读这篇文章:developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS DELETE 方法默认内容类型为:text/plain

以上是关于Angular $http 正在发送 OPTIONS 而不是 PUT/POST的主要内容,如果未能解决你的问题,请参考以下文章

Angularjs 获取 OPTIONS 和 POST 请求

成功登录 API 请求后,Angular 会为每个 API 调用触发额外的 OPTION 请求

Angular $http 未在 OPTIONS 飞行前发送标头

Angular在发送之前获取原始http请求

Angular 2 http 标头似乎生成或发送不正确

Angular $http CORS 405 方法不允许