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
用于 POST
和 PUT
类型的请求。所以你应该做的就是
$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 请求