有人可以解释这两个 http 调用之间的区别以及为啥一个失败而另一个没有?

Posted

技术标签:

【中文标题】有人可以解释这两个 http 调用之间的区别以及为啥一个失败而另一个没有?【英文标题】:Can someone explain the difference between these two http calls and why one fails but the other doesn't?有人可以解释这两个 http 调用之间的区别以及为什么一个失败而另一个没有? 【发布时间】:2016-07-30 05:23:48 【问题描述】:

所以我在工作中继承了一个应用程序,并且遇到了一些我不完全理解的代码。

该应用由一个服务器端 API 和一个调用它的客户端单页应用组成。 Angular 中有一个帐户服务调用 API 进行登录。 API 为 API 的域设置了一个 auth cookie,我们都准备好继续发出经过身份验证的 API 请求。

我不明白的是,为什么项目的前任所有者必须对进入 API 的数据进行 urlencode 并在 Content-Type 标头中包含 application/x-www-form-urlencoded 值。

var qs = require('qs');
var user =  username: 'someUser', password: 'somePassword' ;
$http.post(`$API_URL/login`, qs.stringify(user), 
  headers:  'Content-Type': 'application/x-www-form-urlencoded' 
);

然后,此请求会从 API_URL/login 重定向到 API_URL/account,这会将现在登录的帐户对象返回给应用程序。上面的代码一切正常,我只是不完全理解为什么需要对数据进行 url 编码。如果我删除 Content-Type 标头并且不对数据进行 url 编码,则会收到以下 CORS 错误(API 服务器在 localhost:5000 本地运行,客户端应用程序在 localhost:3000 本地运行。CORS 在服务器允许来自 localhost:3000 的跨域请求):

XMLHttpRequest 无法加载 http://localhost:5000/login。该请求被重定向到“http://localhost:5000/account”,这对于需要预检的跨域请求是不允许的。

var user =  username: 'someUser', password: 'somePassword' ;
$http.post(`$API_URL/login`, user);

谁能解释这里发生了什么?它不像 URL 编码数据正在改变请求被重定向的事实,但它在第一种情况下成功并按预期响应,但在第二种情况下抛出 CORS 错误。

【问题讨论】:

【参考方案1】:

服务器设置为仅接受 URL 编码的表单数据。当您删除该标头时,您将发布一个原始 JSON 正文,服务器不太了解该正文。看起来请求被重定向到不接受其域来源之外的 HTTP 请求的帐户路由。如果您发送标头,您应该会看到相同的错误

Content-Type: application/json

【讨论】:

我相信这是我不包含时默认的标题。我仍然有点困惑,因为帐户服务中还有其他方法可以在没有 url 编码的情况下进行 POST,而且它们似乎工作正常。 $http.post(`$API_URL/cashout`, userId: userId )。那个似乎工作正常,他们没有对数据进行 url 编码或更改内容类型标题。 这是服务器端问题。当需要 URL 编码数据时,服务器需要一个 Web 表单,但兑现被设计为用于跨源调用的 Rest API。你有关于服务器 API 的文档 是的,我控制着服务器。我在本地运行这两个应用程序。 API 是使用 Swagger 设置的。我会做更多的挖掘。感谢您的帮助。 如果您将其张贴在答案中,很高兴查看 swagger 文档 当然,如果你能做到的话:) gist.github.com/chevex/d768b23592bd102ba298303aff4a77c5

以上是关于有人可以解释这两个 http 调用之间的区别以及为啥一个失败而另一个没有?的主要内容,如果未能解决你的问题,请参考以下文章

有人可以向我解释一下逻辑回归中成本函数和梯度下降方程之间的区别吗?

两个更新 SQL 语句之间的区别? [复制]

URI和URL的区别

修改host文件原理 localhost,127.0.0.1之间有什么区别

有人可以解释 GCM 和 Google Pub/Sub 之间的区别吗

NumPy中模数(%)和地板除法(//)之间的区别?