angular获取请求头_angular2 / http获取201响应的位置头

I finished successfully the angular2 "tour of heroes" starter tutorial. Then I build an api based on symfony3, FosRestBundle and BazingaHateoasBundle as backend.

Now nearly everything works, but on creating new items I'm not able to get the "Location" header from the response to load the newly created Item.

Here is my Hero Service:

import {Injectable} from "angular2/core";

import {Hero} from "./hero";

import {Http, Headers, RequestOptions, Response} from "angular2/http";

import {Observable} from "rxjs/Observable";

import "rxjs/Rx";

@Injectable()

export class HeroService {

constructor(private _http:Http) {

}

private _apiUrl = 'http://tour-of-heros.loc/app_dev.php/api'; // Base URL

private _heroesUrl = this._apiUrl + '/heroes'; // URL to the hero api

getHeroes() {

return this._http.get(this._heroesUrl)

.map(res => res.json()._embedded.items)

.do(data => console.log(data)) // eyeball results in the console

.catch(this.handleError);

}

addHero(name:string):Observable {

let body = JSON.stringify({name});

let headers = new Headers({'Content-Type': 'application/json'});

let options = new RequestOptions({headers: headers});

return this._http.post(this._heroesUrl, body, options)

// Hero is created, but unable to get URL from the Location header!

.map((res:Response) => this._http.get(res.headers.get('Location')).map((res:Response) => res.json()))

.catch(this.handleError)

}

private handleError(error:Response) {

// in a real world app, we may send the error to some remote logging infrastructure

// instead of just logging it to the console

console.error(error);

return Observable.throw(error.json().error || 'Server error');

}

getHero(id:number) {

return this._http.get(this._heroesUrl + '/' + id)

.map(res => {

return res.json();

})

.do(data => console.log(data)) // eyeball results in the console

.catch(this.handleError);

}

}

So when I'm calling the addHero method, a new Hero is created and a 201 response is returned without a body, but with the Location header set:

Cache-Control: no-cache

Connection: Keep-Alive

Content-Length: 0

Content-Type: application/json

Date: Tue, 29 Mar 2016 09:24:42 GMT

Keep-Alive: timeout=5, max=100

Location: http://tour-of-heros.loc/app_dev.php/api/heroes/3

Server: Apache/2.4.10 (Debian)

X-Debug-Token: 06323e

X-Debug-Token-Link: /app_dev.php/_profiler/06323e

access-control-allow-credentials: true

access-control-allow-origin: http://172.18.0.10:3000

The problem is, that the res.headers.get('Location') didn't get the Location header from the response.

After some debugging it seems to be that the res.headers just provides two headers Cache-Control and Content-Type. But no Location.

I knew it should be also possible to solve the problem by adding the newly created data to body of the response, but this is not really the way I want to solve this.

Thank you in advance!

解决方案

You should use the flatMap operator instead of the map one:

return this._http.post(this._heroesUrl, body, options)

.flatMap((res:Response) => {

var location = res.headers.get('Location');

return this._http.get(location);

}).map((res:Response) => res.json()))

.catch(this.handleError)

Edit

Regarding your header problem.

I think that your problem is related to CORS. I think that the preflighted request should return the headers to authorize in the Access-Control-Allow-Headers in its response. Something like that:

Access-Control-Allow-Headers:location

If you have the hand on the server side of the call, you could update this header with the headers you want to use on the client side (in your caseLocation`).

I debugged the request and specially within the XhrBackend class that actually executes the request and gets the response from the XHR object. The header isn't returned by the code: _xhr.getAllResponseHeaders(). In my case, I only have the Content-Type one.

From the following question:

Cross-Origin Resource Sharing specification filters the headers that are exposed by getResponseHeader() for non same-origin requests. And that specification forbids access to any response header field other except the simple response header fields (i.e. Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, and Pragma):

See this question for more details:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值