2017-01-03 1 views
3

В настоящее время я пытаюсь получить доступ к API с помощью приложения Angular 2 (через Ionic 2). Наш сервер laravel настроен таким образом, что он ожидает заголовок Accept с типом содержимого запроса и заголовком Content-Type. Не только пустой заголовок Content-Type, но и нет.Как я могу сказать, что Angular 2 автоматически прекратил настройку заголовков Content-Type?

Итак, я настраиваю необходимые параметры в Http, опуская Content-Type в заголовках, и вот тут проблема: Угловая 2, по-видимому, не может удержать руки от Content-Type. Если я дам ему объект как тело запроса, он устанавливает Content-Type в application/json. Это все еще понятно. Затем я строю объект, который вызывает Угловое, чтобы установить Content-Type в text/plain. Попытки через

headers = new Header({Accept: 'application/json', Content-Type: undefined}); 

или

headers.append("Content-Type", undefined); 

или любую другую комбинацию любого заголовка я мог себе представить, что содержит Accept приложения/JSON и ничего другого, даже headers.set или headers.delete терпит неудачу, Угловая 2 продолжает просто делать свое дело.

Установка содержимого-типа в undefined была предложена в другом месте, я также попытался установить его в пустую строку, в application/json при передаче в строчном JSON, Angular просто не дает летающего f ... о что я хочу. Есть ли способ отключить этот автоматизм? Я все еще делаю что-то неправильно (я импортирую заголовки, которые, например, их отсутствие, были проблемой в другом месте, так что это должно быть отключено)?

вот код:

import { Injectable, Inject } from '@angular/core'; 

import { Http, Headers, RequestOptions } from '@angular/http'; 
import 'rxjs/add/operator/toPromise'; 

import { ConfsService } from '../confs/confs.service'; 

import { ApiRequestBody } from './api.request.body'; 

@Injectable() 
export class ApiService { 
    constructor(public confs: ConfsService, private apiRequestBody: ApiRequestBody, private http: Http) { 

    post (method: string, data: any):Promise<any> { 
     const api = this.confs.get().api; 
     const url = api['server'] + "" + api[method]; 
     let allParams = this.apiRequestBody.toJSON(data); 
     let body = JSON.stringify(allParams); 
     let headers = new Headers({ 
      'Accept': 'application/json', 
      'Content-Type': undefined, 
     }); 
     let options = new RequestOptions({ headers: headers });  
     let obj = this.http.post(url, body, options).toPromise(); 
     return obj; 
    } 
} 

ConfsService просто получает несколько параметров конфигурации, ака URL сервера API, и ApiRequestBody получает услугу, которая создает стандартный набор параметров, которые API необходимо даже посмотрите на запрос, в дополнение к тем, которые передаются через параметр данных (который затем сливается с стандартными параметрами в методе toJSON) - никакой науки о ракетах. И я делаю toPromise(), потому что я считаю, что обещание в этом конкретном случае легче обрабатывать.

+1

Есть пара хороших ресурсов на StackOverflow относительно первостепенных/удаления HTTP заголовков в угловых 2 - поиск для них. Это первый, который я нашел: [Как установить HTTP-заголовок по умолчанию в Angular2?] (Http: // stackoverflow.com/questions/34969292/how-to-set-default-http-header-in-angular2) – Adam

+0

спасибо, что указали, что вне этого, проверит его позже – yogibimbi

ответ

1

После копания через угловой исходный код я пришел к выводу, что это невозможно. См. Static_request.ts (https://github.com/angular/angular/blob/5293794316cc1b0f57d5d88b3fefdf6ae29d0d97/packages/http/src/static_request.ts). Сначала будет проверяться, если вы вручную настроили заголовки на определенную строку, а неопределенная или пустая строка попадет в функцию detectContentTypeFromBody, которая будет устанавливать только ContentType.NONE, если ваш тело запроса равно null.

/** 
    * Returns the content type enum based on header options. 
    */ 
    detectContentType(): ContentType { 
    switch (this.headers.get('content-type')) { 
     case 'application/json': 
     return ContentType.JSON; 
     case 'application/x-www-form-urlencoded': 
     return ContentType.FORM; 
     case 'multipart/form-data': 
     return ContentType.FORM_DATA; 
     case 'text/plain': 
     case 'text/html': 
     return ContentType.TEXT; 
     case 'application/octet-stream': 
     return this._body instanceof ArrayBuffer ? ContentType.ARRAY_BUFFER : ContentType.BLOB; 
     default: 
     return this.detectContentTypeFromBody(); 
    } 
    } 

    /** 
    * Returns the content type of request's body based on its type. 
    */ 
    detectContentTypeFromBody(): ContentType { 
    if (this._body == null) { 
     return ContentType.NONE; 
    } else if (this._body instanceof URLSearchParams) { 
     return ContentType.FORM; 
    } else if (this._body instanceof FormData) { 
     return ContentType.FORM_DATA; 
    } else if (this._body instanceof Blob) { 
     return ContentType.BLOB; 
    } else if (this._body instanceof ArrayBuffer) { 
     return ContentType.ARRAY_BUFFER; 
    } else if (this._body && typeof this._body === 'object') { 
     return ContentType.JSON; 
    } else { 
     return ContentType.TEXT; 
    } 
    } 

Update:

Похоже, что на самом деле возможно путем расширения запроса и перегрузки функции detectContentType для возврата 0. Для этого требуется доступ к непубличную кода, хотя так оно может сломаться в будущем:

import {Http, Headers, RequestOptions, RequestMethod, Request, BaseRequestOptions, Response} from '@angular/http'; 
import { ContentType } from '@angular/http/src/enums'; 
import { RequestArgs } from '@angular/http/src/interfaces'; 

class NoContentRequest extends Request { 
    constructor(args: RequestArgs) { 
    super(args); 
    } 
    detectContentType(): ContentType { 
    return 0; 
    } 
} 

const headers = new Headers({Accept: 'application/json'}); 

const request = new NoContentRequest({ 
    method: RequestMethod.Post, 
    url: 'https://www.example.com/example', 
    responseType: ResponseContentType.Json, 
    headers: headers, 
    body: body 
}); 

this._http.request(request) 
    .catch((error: Response | any) => { console.error(error); return Observable.throw(error); }) 
    .first() 
    .subscribe(); 
+1

wow, довольно немного взломанный. Удивлен, что в Angular нет ничего более _legal_. Очень хорошо! – yogibimbi

0

Я думаю, что лучший способ - удалить заголовок Content-Type из запроса.

т.е.

 this.http.post(apiUrl, request, { 
     headers: new HttpHeaders().delete('Content-Type') 
    }); 
+0

Это не работает для меня –

Смежные вопросы