选项(失败)仅在 Chrome 和 Firefox 上

Posted

技术标签:

【中文标题】选项(失败)仅在 Chrome 和 Firefox 上【英文标题】:OPTIONS (failed) only on Chrome and Firefox 【发布时间】:2016-10-14 21:55:48 【问题描述】:

我发出一个 POST 请求,但该请求一直处于等待状态,直到最终失败。我已经监视了 nginx 日志和节点服务器日志,并且请求甚至没有注册。这适用于我测试过的其他任何人,除了另一位同事。如果我使用边缘浏览器或其他计算机,它可以正常工作。

我试图向其他(自定义)服务器发出 POST 请求,它也挂在那里的选项上。我也用 jQuery 发出了 POST 请求,但同样失败了。

值得注意的是,我正在使用 withCredentials 标志。

标题:

Provisional headers are shown
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:GET
Origin:http://localhost:8080
Referer:http://localhost:8080/<path>
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/51.0.2704.84 Safari/537.36

请求:

  public login(user) 
    const endpoint = `http://<url>`;

    let headers = new Headers();
    headers.append('Content-type', 'application/json');

    return this.http
      .post(endpoint, JSON.stringify(user), 
        headers: headers,
      );

  

我在我的组件中订阅了调用:

this._accountService.login(this.user)
        .subscribe(res => 
            console.log("logged in!");
            if (res.json().status === "success") 
                window.location.href = `/home/$this.org/$this.product`;
            
            else 
                // What other options are there?
                console.log("Do something else maybe?");
            
        ,
        err => 
            this.invalidLogin = true;
            console.log("Ye shall not pass!");
        );

成功用户的标题

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:<url>
Origin:<url>
Referer:<url>
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.33 Safari/537.36

来自 chrome://net-internals/#events

t=61869793 [st=    0] +REQUEST_ALIVE  [dt=60162]
                       --> has_upload = false
                       --> is_pending = true
                       --> load_flags = 34624 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | MAYBE_USER_GESTURE | VERIFY_EV_CERT)
                       --> load_state = 14 (WAITING_FOR_RESPONSE)
                       --> method = "OPTIONS"
                       --> net_error = -1 (ERR_IO_PENDING)
                       --> status = "IO_PENDING"
                       --> url = "<url>"
t=61929955 [st=60162]   -HTTP_STREAM_PARSER_READ_HEADERS
                         --> net_error = -324 (ERR_EMPTY_RESPONSE)
t=61929955 [st=60162]   -HTTP_TRANSACTION_READ_HEADERS
                         --> net_error = -324 (ERR_EMPTY_RESPONSE)
t=61929955 [st=60162]   -URL_REQUEST_START_JOB
                         --> net_error = -324 (ERR_EMPTY_RESPONSE)
t=61929955 [st=60162]    URL_REQUEST_DELEGATE  [dt=0]
t=61929955 [st=60162] -REQUEST_ALIVE
                       --> net_error = -324 (ERR_EMPTY_RESPONSE)

我真的猜测这与我的浏览器中缓存的某些内容有关,但我真的找不到什么。我已经清除了所有 cookie 和任何可以存储的东西。我还能在哪里检查以清除东西?这显然是我的计算机/浏览器(以及另一个不幸的人)本地的东西。

【问题讨论】:

***.com/questions/10143093/… 这与 Angular 无关。您正在访问的服务器需要支持 CORS 请求。 OPTIONS 是浏览器自动发出的预检请求。如果它没有返回预期的Access-Control-Allow-... 标头,它甚至不会尝试发送实际请求。 @GünterZöchbauer 我启用了 CORS。该请求适用于其他计算机和浏览器。 您需要发布服务器接收到的标头以及它响应 OPTIONS 请求的标头,以便任何人都能够提供帮助。从计算机发出的请求中查看发送的标头会很有帮助,这些请求也适用于比较。 @GünterZöchbauer 好电话,我已相应更新。 【参考方案1】:

请尝试 subscribe() 到 observable。

return this.http
  .post(endpoint, JSON.stringify(user), 
    headers: headers,
  ).subscribe(() => console.log("POST done!"));

【讨论】:

对不起,这只是我的服务,由我的组件调用。我的组件已订阅。我应该澄清一下。 @Aarmora 您是否尝试进入 post call 以查看它执行的最后一步是什么? 它进行了完整的调用,但请求只是挂在挂起。由于连接被拒绝,没有回调返回。 @Aarmora 尝试查看 chrome://net-internals (事件),看看您是否看到它挂起的原因。 这真的很有趣!我在上面添加了回报。它给你任何想法吗?【参考方案2】:

您是否尝试在标题中设置“缓存控制”?我认为在 jQuery 中你可以简单地设置

$.ajax(    
  cache: false 
);

或使用常规 ajax 请求添加标头

request.setRequestHeader("Cache-Control", "no-cache"); 

【讨论】:

我没听说过这个。我只是尝试了一下,并没有得到不同的结果。不过建议很好。【参考方案3】:

你为什么不阻止进入OPTIONS请求循环。它有时真的让你发疯。其他浏览器不会触发 OPTIONS 请求,但 chrome 和 firefox 会确保 CORS 。我已经成功地使用了这个来自 github 的名为 xdomain 的库,它确实有效!他们的 github 介绍页面将 xdomain 介绍为 CORS alternative 。最重要的是我在 JQuery 中使用了它,但它也支持 Angular 的 http 服务。看看它 。它可能对你有好处:)。这是图书馆的链接Xdomain CORS Alternative

【讨论】:

【参考方案4】:

CORS 和使用 localhost 作为域(您已在 ORIGIN 标头中列出)存在问题。通常,当涉及到localhost 时,出于某些安全原因,CORS / OPTIONS 请求无法正常工作,但挂起通常不会发生,因此这可能不是正确的答案,但值得一试!

尝试将新主机添加到本地计算机并从等式中删除 localhost。只是把这个想法扔在那里,希望它可以帮助你!

根据下面的评论

您的服务器似乎允许连接,但似乎没有发送响应。您能否发布成功的 OPTIONS 请求的标头,以证明服务器确实能够处理这些请求。

【讨论】:

不幸的是,当从 localhost 或从具有域和 DNS 集的网络服务器调用时,也会发生同样的事情。不过,谢谢。 另一件事是您的服务器由于某些逻辑问题而没有返回响应,无论是通过 cookie / 凭证或其他原因。您是否能够添加处理这些请求的服务器端代码的 POST 和 OPTION 端点? 是的,服务器在 Edge 上对其他人或我来说都可以正常工作。它仅不适用于 Chrome 和 firefox。 您的日志看起来好像您正在建立连接,但您的服务器没有返回表明服务器端存在问题的响应。此外,只需检查您的大学是否也在设置 xdomain 情况以实际创建 OPTIONS 预检,因为您包含的返回标头用于 POST 响应,而不是 OPTIONS 响应。 即是否有证据表明服务器确实返回了 OPTIONS 200||204 OK 标头。

以上是关于选项(失败)仅在 Chrome 和 Firefox 上的主要内容,如果未能解决你的问题,请参考以下文章

Viewstate 仅在 IE 中失败

正则表达式仅在 Safari 上失败

Http/2 站点仅在 Safari 9 上无法加载 - 在 Chrome、IE、Edge、Firefox 上加载正常

Firefox 在 CORS 资源上失败,而 Chrome 和 Safari 工作

Angular 跨域请求在 Chrome 上有效,在 Firefox 和 IE 上失败

在 Firefox 和 Internet Explorer 中解析 DateTime 字符串失败,适用于 Chrome