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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30254277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:51:51  来源:igfitidea点击:

Angular $http is sending OPTIONS instead of PUT/POST

javascriptjsonangularjs

提问by Bastian Gruber

I am trying to Update/Insert data in a MySQL database through a PHP backend. I'm building the Front End with AngularJS and using the $httpservice for communicating with the REST API.

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

My setup looks like this:

我的设置如下所示:

I'm setting the header via the $httpProvider:

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

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

And the POST-Call looks like this:

POST-Call 如下所示:

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

The Dev Console in Chrome shows me this:

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

enter image description here

在此处输入图片说明

When I change from POST to PUT, I'm sending an OPTIONS call instead a PUT. And the content-type switches just to content-type.

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

My request payload is send as an object:

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

enter image description here

在此处输入图片说明

How do I set my header properly?

如何正确设置我的标题?



EDIT:

编辑:

The PHP backend sets some headers:

PHP 后端设置了一些标头:

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

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

Is there something missing?

有什么遗漏吗?

回答by Bastian Gruber

Ok, I've solved it.

好的,我已经解决了。

What was the problem?
The CORS workflow for DELETE, PUT and POST is as follows:

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

enter image description here

在此处输入图片说明

What it does, is:

它的作用是:

  1. Checking which request is gonna be made
  2. If it's POST, PUT or DELETE
  3. It sends first an OPTION request to check if the domain, from which the request is sent, is the same as the one from the server.
  4. If not, it wants an Access-Header to be allowed to send this request
  1. 检查将要发出哪个请求
  2. 如果是 POST、PUT 或 DELETE
  3. 它首先发送一个 OPTION 请求以检查发送请求的域是否与来自服务器的域相同。
  4. 如果没有,它希望允许访问头发送此请求

Important here: An OPTIONS request doesn't send credentials.

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

So my backend server disallowed the PUT request.

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

Solution:
Putting this inside the .htaccessfile

解决方案:
将其放入.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"

After this, create an empty .php file called blank.php inside the public folder.

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

EDIT: As one commenter pointed out, instead of creating an empty PHP file, you can add this rewrite rule to your .htaccess file\;

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

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

To clarify:

澄清:

  1. I already sent the Access-Control-Header
  2. What it solved was the first two lines, and
  3. Access-Control-Allow-Origin from the specific subdomain with Port
  1. 我已经发送了 Access-Control-Header
  2. 它解决的是前两行,以及
  3. 来自带有端口的特定子域的 Access-Control-Allow-Origin

Best website I could find to learn more about CORS.

我能找到的最好的网站,以了解有关 CORS 的更多信息

回答by Dan Moldovan

You don't need to specify your $httpheaders manually, it is all done for you behind the scenes and they are automatically set to application/jsonfor POSTand PUTtype requests. So all that you should do is

您不需要$http手动指定您的标头,这一切都是在幕后为您完成的,它们会自动设置为application/jsonforPOSTPUTtype requests。所以你应该做的就是

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