Angular2:angular-http 标头非常奇怪的行为
Posted
技术标签:
【中文标题】Angular2:angular-http 标头非常奇怪的行为【英文标题】:Angular2: angular-http Headers very strange behaviour 【发布时间】:2017-05-28 19:23:14 【问题描述】:我正在开发一个非常基本的 angular2 Web 应用程序,但遇到了一些与 http 标头有关的问题...
我有以下功能:
postStockTake(stockTakeModel: StockTakeModel) : Observable<Response>
let body = JSON.stringify(stockTakeModel);
let hd = new Headers();
hd.append('Content-Type', 'application/json');
return this.http.post(ApiUrl, body, headers: hd)
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'server error'));
当我从标头中省略 hd.append('Content-Type', 'application/json') 语句时,我实际上得到了来自服务器的响应,但它随后抱怨负载在应该是原始格式时是原始格式一个json。当我添加“Content-Type”、“application/json”标头时,它根本不起作用,并且在我的 crhome 控制台中出现“加载资源失败:CONNECTION_RESET”错误... 使用 Rest Client 时,我可以毫无问题地使用上述标头进行发布请求,所以我不知道为什么会发生这种情况......我必须在我的应用程序中为另一个 put 请求添加此标头并获得相同结果。
当我在省略标头时查看标头下的 chrome 开发工具网络选项卡时,我在请求标头下看到以下标头:
请求标头: 接受:application/json、text/plain、/ 接受编码:gzip、deflate、sdch 接受语言:en-US,en;q=0.8 连接:保持活动 主机:10.60.160.34 内容类型:文本/纯文本 来源:http://localhost:4200 推荐人:http://localhost:4200/settings 用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/55.0.2883.87 Safari/537.36
当我添加标头时,我在 chrome 开发工具的请求标头下得到以下信息:
显示临时标题 访问控制请求标头:内容类型 访问控制请求方法:GET 来源:http://localhost:4200 推荐人:http://localhost:4200/settings 用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
所以添加时我什至没有在标题中看到我的应用程序/json?知道为什么会发生这种情况/我能做些什么来解决它吗?
更新:从 chrome://net-internals 我看到以下内容:
http://10.60.160.34/BRMServices/WebEnquiry/StockTake/AddToStockTake
Start Time: 2017-01-13 14:44:30.800
t=19711 [st=0] +REQUEST_ALIVE [dt=3]
t=19711 [st=0] URL_REQUEST_DELEGATE [dt=0]
t=19711 [st=0] +URL_REQUEST_START_JOB [dt=3]
--> load_flags = 34624 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | MAYBE_USER_GESTURE | VERIFY_EV_CERT)
--> method = "OPTIONS"
--> priority = "MEDIUM"
--> url = "http://10.60.160.34/BRMServices/WebEnquiry/StockTake/AddToStockTake"
t=19711 [st=0] URL_REQUEST_DELEGATE [dt=0]
t=19711 [st=0] HTTP_CACHE_GET_BACKEND [dt=0]
t=19711 [st=0] +HTTP_STREAM_REQUEST [dt=1]
t=19711 [st=0] HTTP_STREAM_REQUEST_STARTED_JOB
--> source_dependency = 6474 (HTTP_STREAM_JOB)
t=19712 [st=1] HTTP_STREAM_REQUEST_BOUND_TO_JOB
--> source_dependency = 6474 (HTTP_STREAM_JOB)
t=19712 [st=1] -HTTP_STREAM_REQUEST
t=19712 [st=1] +HTTP_TRANSACTION_SEND_REQUEST [dt=0]
t=19712 [st=1] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> OPTIONS /BRMServices/WebEnquiry/StockTake/AddToStockTake HTTP/1.1
Host: 10.60.160.34
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: http://localhost:4200/stockTake
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
t=19712 [st=1] -HTTP_TRANSACTION_SEND_REQUEST
t=19712 [st=1] +HTTP_TRANSACTION_READ_HEADERS [dt=2]
t=19712 [st=1] HTTP_STREAM_PARSER_READ_HEADERS [dt=2]
--> net_error = -101 (ERR_CONNECTION_RESET)
t=19714 [st=3] -HTTP_TRANSACTION_READ_HEADERS
--> net_error = -101 (ERR_CONNECTION_RESET)
t=19714 [st=3] -URL_REQUEST_START_JOB
--> net_error = -101 (ERR_CONNECTION_RESET)
t=19714 [st=3] URL_REQUEST_DELEGATE [dt=0]
t=19714 [st=3] -REQUEST_ALIVE
--> net_error = -101 (ERR_CONNECTION_RESET)
【问题讨论】:
GET 请求通常不使用 Content-Type 标头,而是使用 Accept 标头。您确定需要在此处使用 Content-Type 标头吗? 您的代码表面上看起来不错。但是,您似乎遇到了 CORS 问题。您问题中的第二个请求实际上是 GET 还是 OPTIONS 请求? @MikeOne 我开始遇到此问题的第二个未添加到此问题的请求是帖子。虽然这个 ping 请求是一个 get ......我在这里尝试复制我在这个 get 请求中的 Post 请求中遇到的问题,看看它的行为是否相同(它确实...... 当我在没有添加此标头的情况下执行最初遇到此问题的 Post 请求时,我实际上得到了来自服务器的响应,但是当我添加标头时,我什么也没得到……就像请求被标头阻止 只是为了确保。您可能会告诉它执行 POST(或 GET),但如果存在 CORS 问题(即某些类型的跨域请求) - 浏览器本身首先会执行预检 OPTIONS 请求(可能不包含您的自定义集标头)。在 CORS 请求上设置“内容类型”会导致请求从“简单”请求变为“复杂”请求(触发预检选项)。您可能正在查看此 OPTIONS 请求,而不是您期望的实际请求。因此问题。 【参考方案1】:你需要把构造函数中的细节作为一个对象放在http之前
hd = new Header("Content-Type" : "application/json");
【讨论】:
我最初是这样做的,但得到了完全相同的错误,这就是我尝试这种方式的原因......【参考方案2】:您的代码表面上看起来不错。但是,您似乎可能会遇到 CORS 问题。您问题中的第二个请求实际上是 GET 还是 OPTIONS 请求?
只是为了确定。您可能会告诉它执行 POST(或 GET),但如果存在 CORS 问题(即某些类型的跨域请求) - 浏览器本身首先会执行预检 OPTIONS 请求(可能不包含您的自定义集标头)。在 CORS 请求上设置“内容类型”会导致请求从“简单”请求变为“复杂”请求(触发预检选项)。您可能正在查看此 OPTIONS 请求,而不是您期望的实际请求。因此问题。
【讨论】:
再次感谢@MikeOne。因此,如果我正确理解这一点,即使它是跨域的,get 请求也可以工作,因为它没有触发预检标头,因为我没有向请求添加内容类型标头? 确实!这可能是原因。以上是关于Angular2:angular-http 标头非常奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章
Angular2 - HTTP RequestOptions 标头
Angular2 Spring Boot JWT 缺少响应标头
Angular2 中的 Apollo 客户端自定义标头和附加变量