简体   繁体   English

Angular2 中 Http.DELETE 请求的正文

[英]Body of Http.DELETE request in Angular2

I'm trying to talk to a somewhat RESTful API from an Angular 2 frontend.我正在尝试从 Angular 2 前端与有点 RESTful API 交谈。

To remove some item from a collection, I need to send some other data in addition to the removée unique id(that can be appended to the url), namely an authentication token, some collection info and some ancilliary data.要从集合中删除某些项目,除了删除的唯一 ID(可以附加到 url)之外,我还需要发送一些其他数据,即身份验证令牌、一些集合信息和一些辅助数据。

The most straightforward way I've found to do so is putting the authentication token in the request Headers, and other data in the body.我发现这样做最直接的方法是将身份验证令牌放在请求标头中,并将其他数据放在正文中。

However, the Http module of Angular 2 doesn't quite approve of a DELETE request with a body, and trying to make this request但是,Angular 2 的 Http 模块并不完全同意带有主体的 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

gives this error给出这个错误

app/services/test.service.ts(67,4): error TS2346: Supplied parameters do not match any signature of call target.

Now, am I doing something wrong syntax-wise?现在,我在语法方面做错了吗? I'm pretty sure a DELETE body is supported per RFC我很确定每个 RFC 都支持 DELETE 正文

Are there better ways to send that data?有没有更好的方法来发送这些数据?

Or should I just dump it in headers and call it a day?还是我应该将其转储到标题中并收工?

Any insight on this conundrum would be appreciated对此难题的任何见解将不胜感激

The http.delete(url, options) does accept a body. http.delete(url, options)确实接受正文。 You just need to put it within the options object.您只需将其放在选项对象中。

http.delete('/api/something', new RequestOptions({
   headers: headers,
   body: anyObject
}))

Reference options interface: https://angular.io/api/http/RequestOptions参考选项接口: https ://angular.io/api/http/RequestOptions

UPDATE :更新

The above snippet only works for Angular 2.x, 4.x and 5.x.上面的代码片段仅适用于 Angular 2.x、4.x 和 5.x。

For versions 6.x onwards, Angular offers 15 different overloads.对于 6.x 以后的版本,Angular 提供了 15 种不同的重载。 Check all overloads here: https://angular.io/api/common/http/HttpClient#delete在此处检查所有重载: https ://angular.io/api/common/http/HttpClient#delete

Usage sample:使用示例:

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);
  });

If you use Angular 6 we can put body in http.request method.如果您使用 Angular 6,我们可以将 body 放入http.request方法中。

Reference from github 来自github的参考

You can try this, for me it works.你可以试试这个,对我来说它有效。

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();
  }
}

In Angular 5, I had to use the request method instead of delete to send a body.在 Angular 5 中,我必须使用request方法而不是delete来发送正文。 The documentation for the delete method does not include body , but it is included in the request method. delete方法的文档不包括body ,但它包含在 request 方法中。

import { HttpClient, HttpHeaders } from '@angular/common/http';

this.http.request('DELETE', url, {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
  }),
  body: { foo: bar }
});

You are actually able to fool Angular2 HTTP into sending a body with a DELETE by using the request method.实际上,您可以使用request方法欺骗Angular2 HTTP发送带有DELETEbody This is how:这是如何:

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)});

Note, you will have to set the request method in the RequestOptionsArgs and not in http.request 's alternative first parameter Request .请注意,您必须在RequestOptionsArgs中设置请求方法,而不是在http.request的替代第一个参数Request中。 That for some reason yields the same result as using http.delete由于某种原因,这会产生与使用http.delete相同的结果

I hope this helps and that I am not to late.我希望这会有所帮助,而且我不会迟到。 I think the angular guys are wrong here to not allow a body to be passed with delete, even though it is discouraged.我认为有角的人在这里不允许通过删除传递身体是错误的,即使不鼓励这样做。

Below is a relevant code example for Angular 4/5 with the new HttpClient.下面是带有新 HttpClient 的 Angular 4/5 的相关代码示例。

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);
  }

For angular 10, you can use also the generic request format and the DELETE method:对于 Angular 10,您还可以使用通用请求格式和 DELETE 方法:

http.request('DELETE',  path, {
            body:body,
            headers: httpHeaders,
            params: ((params != null) ? params : new HttpParams())
        })

Below is an example for Angular 6以下是 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);
        }

The REST doesn't prevent body inclusion with DELETE request but it is better to use query string as it is most standarized (unless you need the data to be encrypted) REST 不会阻止包含 DELETE 请求的正文,但最好使用查询字符串,因为它是最标准化的(除非您需要加密数据)

I got it to work with angular 2 by doing following:我通过执行以下操作使其与 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(...)

Below is the relevant code example for Angular 2/4/5 projects:以下是 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;
  });

Notice that body is passed through RequestOptions请注意, body是通过RequestOptions传递的

In Angular Http 7, the DELETE method accepts as a second parameter options object in which you provide the request parameters as params object along with the headers object.在 Angular Http 7 中,DELETE 方法接受作为第二个参数options对象,您可以在其中提供请求参数作为params对象以及headers对象。 This is different than Angular6.这与 Angular6 不同。

See example:参见示例:

this.httpClient.delete('https://api-url', {
    headers: {},
    params: {
        'param1': paramValue1,
        'param2': paramValue2
    }
});
deleteInsurance(insuranceId: any) {
    const insuranceData = {
      id : insuranceId
    }
    var reqHeader = new HttpHeaders({
            "Content-Type": "application/json",
        });
        const httpOptions = {
            headers: reqHeader,
            body: insuranceData,
        };
    return this.http.delete<any>(this.url + "users/insurance", httpOptions);
    }

In Angular 13 this works well for me:在 Angular 13 中,这对我很有效:

const options = {
   headers: this._headers,
   body: JSON.stringify(user)
};

return this._http.delete<DeleteVirtualAssistantResult>(`${this._apiUrl}/users`, options);

Since the deprecation of RequestOptions , sending data as body in a DELETE request is not supported.由于弃用RequestOptions ,因此不支持在 DELETE 请求中将数据作为正文发送。

If you look at the definition of DELETE , it looks like this:如果您查看DELETE的定义,它看起来像这样:

    delete<T>(url: string, options?: {
      headers?: HttpHeaders | {
         [header: string]: string | string[];
        };
      observe?: 'body';
      params?: HttpParams | {
          [param: string]: string | string[];
         };
      reportProgress?: boolean;
      responseType?: 'json';
      withCredentials?: boolean;
     }): Observable<T>;

You can send payload along with the DELETE request as part of the params in the options object as follows:您可以将有效负载与 DELETE 请求一起作为选项对象中参数的一部分发送,如下所示:

this.http.delete('http://testAPI:3000/stuff', { params: {
    data: yourData
     }).subscribe((data)=>. 
        {console.log(data)});

However, note that params only accept data as string or string[] so you will not be able to send your own interface data unless you stringify it.但是,请注意 params 只接受字符串string[]形式的数据,因此除非将其字符串化,否则您将无法发送自己的接口数据。

Definition in http.js from the @angular/http : @angular/http在 http.js 中的定义:

delete(url, options)删除(网址,选项)

The request doesn't accept a body so it seem your only option is to but your data in the URI.该请求不接受正文,因此您唯一的选择似乎是 URI 中的数据。

I found another topic with references to correspond RFC, among other things: How to pass data in the ajax DELETE request other than headers我发现了另一个主题,其中引用了对应的 RFC,其中包括: 如何在 ajax DELETE 请求中传递数据而不是标头

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM