Тело запроса Http.DELETE в Angular2
Я пытаюсь поговорить с несколько RESTful API с интерфейсом Angular 2.
Чтобы удалить какой-либо элемент из коллекции, мне нужно отправить другие данные в дополнение к уникальному идентификатору удаления (который может быть добавлен к URL-адресу), а именно токен аутентификации, некоторая информация о коллекции и некоторые вспомогательные данные.
Самый простой способ, которым я нашел это, - положить маркер аутентификации в заголовки запроса и другие данные в теле.
Однако модуль Http Angular 2 не одобряет запрос DELETE с телом и пытается сделать этот запрос
let headers= new Headers();
headers.append('access-token', token);
let body= JSON.stringify({
target: targetId,
subset: "fruits",
reason: "rotten"
});
let options= new RequestOptions({headers:headers});
this.http.delete('http://testAPI:3000/stuff', body,options).subscribe((ok)=>{console.log(ok)}); <------line 67
дает эту ошибку
app/services/test.service.ts(67,4): error TS2346: Supplied parameters do not match any signature of call target.
Теперь я делаю что-то неправильное по синтаксису? Я уверен, что тело DELETE поддерживается в RFC
Есть ли способы отправить эти данные более эффективными способами?
Или я должен просто сбрасывать его в заголовках и называть его днем?
Любое понимание этой головоломки было бы оценено
Ответы
Ответ 1
Определение в http.js из @angular/http:
delete (url, options)
Запрос не принимает тело, поэтому кажется, что ваш единственный вариант - это только ваши данные в URI.
Я нашел еще одну тему со ссылками на соответствующие RFC, среди прочего:
Как передать данные в запросе ajax DELETE, отличном от заголовков.
Ответ 2
Http.delete(url, options) принимает тело. Вам просто нужно поместить его в объект параметров.
http.delete('/api/something', new RequestOptions({
headers: headers,
body: anyObject
}))
Справочные параметры интерфейса:
https://angular.io/api/http/RequestOptions
ОБНОВЛЕНИЕ:
Приведенный выше фрагмент работает только для Angular 2.x, 4.x и 5.x.
Для версий 6.x и 7.x Angular предлагает различные перегрузки для того, что вам нужно. Проверьте все перегрузки здесь: https://angular.io/api/common/http/HttpClient#delete
const options = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
body: {
id: 1,
name: 'test',
},
};
this.httpClient
.delete('http://localhost:8080/something', options)
.subscribe((s) => {
console.log(s);
});
Ответ 3
На самом деле вы можете обмануть Angular2 HTTP
при отправке body
с помощью DELETE
с помощью метода request
. Вот как это делается:
let body = {
target: targetId,
subset: "fruits",
reason: "rotten"
};
let options = new RequestOptionsArgs({
body: body,
method: RequestMethod.Delete
});
this.http.request('http://testAPI:3000/stuff', options)
.subscribe((ok)=>{console.log(ok)});
Примечание. Вам нужно будет установить метод запроса в RequestOptionsArgs
, а не в http.request
альтернативном первом параметре request
. Это по какой-то причине дает тот же результат, что и при использовании http.delete
Надеюсь, это поможет, и я не опаздываю. Я думаю, что ребята из angular ошибаются здесь, чтобы не допускать, чтобы тело передавалось с удалением, даже если оно не поощряется.
Ответ 4
В Angular 5 мне пришлось использовать метод request вместо delete для отправки тела. Документация по методу удаления не включает тело, но оно включено в метод запроса.
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
this.http.request('DELETE', url, {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
body: { foo: bar }
});
Ответ 5
Если вы используете Angular 6, мы можем поместить тело в метод http.request
.
Отзыв от GitHub
Вы можете попробовать это, для меня это работает.
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(
private http: HttpClient
) {
http.request('delete', url, {body: body}).subscribe();
}
}
Ответ 6
Ниже приведен пример кода для Angular 4/5 с новым HttpClient.
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
public removeItem(item) {
let options = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
body: item,
};
return this._http
.delete('/api/menu-items', options)
.map((response: Response) => response)
.toPromise()
.catch(this.handleError);
}
Ответ 7
Ниже приведен пример для Angular 6
deleteAccount(email) {
const header: HttpHeaders = new HttpHeaders()
.append('Content-Type', 'application/json; charset=UTF-8')
.append('Authorization', 'Bearer ' + sessionStorage.getItem('accessToken'));
const httpOptions = {
headers: header,
body: { Email: email }
};
return this.http.delete<any>(AppSettings.API_ENDPOINT + '/api/Account/DeleteAccount', httpOptions);
}
Ответ 8
REST не предотвращает включение тела с запросом DELETE, но лучше использовать строку запроса, поскольку она наиболее стандартизирована (если вам не нужны данные, которые нужно зашифровать)
Я получил его для работы с angular 2, выполнив следующие действия:
let options:any = {}
option.header = new Headers({
'header_name':'value'
});
options.search = new URLSearchParams();
options.search.set("query_string_key", "query_string_value");
this.http.delete("/your/url", options).subscribe(...)
Ответ 9
Ниже приведен соответствующий пример кода для проектов Angular 2/4/5:
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({
headers: headers,
body: {
id: 123
}
});
return this.http.delete("http//delete.example.com/delete", options)
.map((response: Response) => {
return response.json()
})
.catch(err => {
return err;
});
Обратите внимание, что body
передается через RequestOptions
Ответ 10
В Angular Http 7 метод DELETE принимает в качестве объекта второго параметра options
, в котором вы предоставляете параметры запроса как объект params
вместе с объектом headers
. Это отличается от Angular6.
Смотрите пример:
this.httpClient.delete('https://api-url', {
headers: {},
params: {
'param1': paramValue1,
'param2': paramValue2
}
});