HTTP POST 变成 OPTIONS AngularJS

Posted

技术标签:

【中文标题】HTTP POST 变成 OPTIONS AngularJS【英文标题】:HTTP POST turns into OPTIONS AngularJS 【发布时间】:2016-12-08 21:34:45 【问题描述】:

我正在尝试将登录表单提交给 rest Api,将我的 Jquery/javascript 代码翻译成 AngularJS。我尝试使用$http 服务发送请求,但是当我提交表单时,POST 请求变成了 OPTIONS 并且没有传递请求参数。这是我的代码:

controller.formData = 
    username :  $scope.formData.username,
    password :  $scope.formData.password,
;
$http(
      method  : 'POST',
      url     : 'http://localhost:8080/multe-web/signin',
      data    : controller.formData,  
      headers :  'Content-Type': 'application/json'   
     )
    .success(function(data) 
        console.log(data);
     );

这是浏览器控制台的屏幕截图

为什么没有参数传递给 HTTP POST 请求?

有人可以帮助我吗?

【问题讨论】:

我相信您遇到了 cors 政策问题。浏览器将使用选项请求预检您的帖子。 我编辑问题。 【参考方案1】:

您必须在后端定义 CORS 过滤器。 我不知道您使用的是哪种语言,但以下是 spring 框架 (java) 中的示例。

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter 

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, cache-control, content-type, Origin, key");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) 
            response.setStatus(HttpServletResponse.SC_OK);
         else 
            chain.doFilter(req, res);
        
    

    @Override
    public void init(FilterConfig filterConfig) 
    

    @Override
    public void destroy() 
    

基本上你是说response.setHeader("Access-Control-Allow-Origin", "*"); 可以来自任何域。 (在生产环境中,您可以将此课程限制在您的已知域中)。

实施此过滤器时,您的选项请求将毫无问题地通过。

选项调用是浏览器自动执行的操作,您真的不想像其他一些答案所建议的那样禁用它。

亲切的问候

【讨论】:

在我的后端 CORS 已经启用。问题是在 HTTP POST 正文中没有传递任何参数(查看上面问题中的第二个屏幕截图)。我该如何解决这个问题? 请告诉我你定义休息端点的后端代码【参考方案2】:

您看到的OPTIONS 是由浏览器发起的预发送请求。这是因为CORS 代表“跨源资源共享”。

Pre-flighted requests

在您的情况下,您的后端服务器需要确认 OPTIONS 请求并返回 200。只有这样浏览器才会触发真正的POST 请求

这里有一些链接可以帮助您入门 Same Origin policyAngularJS and CORSSimilar question on SO

【讨论】:

我应该如何更改我的源代码来完成这个? 所以,您的后端需要通过 200 确认 OPTIONS。您的后端有什么样的服务器? Java/NodeJs..等? 我的后端是 Java 服务器。 尝试these 主题。这个想法是让您的服务器为选项发送 200。并相应地应用安全策略 在我的后端启用了 CORS。 HTTP POST 没有任何请求参数,所以我认为这是真正的问题。【参考方案3】:

此请求称为“预检请求”。当您尝试访问来自另一个域的资源时,这会附加。有关更多信息,您可以搜索跨域资源共享 (CORS)。在预检请求期间,您应该看到以Access-Control-Request-* 开头的标头这些请求标头正在向服务器请求权限以发出实际请求。您的预检响应需要确认这些标头才能使实际请求生效。

【讨论】:

我应该如何更改我的源代码来完成这个? 您可以在同一个域中托管您的网页和您的 api。或者您可以在 Web 服务器上处理 OPTIONS 请求以返回预期的标头【参考方案4】:

如果您尝试执行跨域请求,这可能是 'preflight request'

看到这个帖子:How to disable OPTIONS request?

【讨论】:

我应该如何更改我的源代码来完成这个?

以上是关于HTTP POST 变成 OPTIONS AngularJS的主要内容,如果未能解决你的问题,请参考以下文章

ZF2中的CORS POST请求变成OPTIONS请求

post 变成option 请求的三种原因

[Angularjs]$http.post与$.post

$http.post 在 Rails 路由中变为 [OPTIONS]

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

在 Angular 2 http.post 上添加任何选项或标题会发送 OPTIONS