-1

I set up an API with the GET method on the server which, by giving it an authorization token and a body in which a code is specified, returns the info of an object with the same code (it's a serial number). I've tried this code (lookFor is my serial number):

getInfoMatricola(matricola: string,_token: string){
  fetch(this.url, {
   method: 'GET',
   headers: {
   Authorization: `Bearer ${_token}`
   },
   body: ` lookFor":"${matricola} `,
   })
    .then((response) => response.json())
    .then((data) => {
    console.log('Success:', data);
    })
    .catch((error) => {
    console.error('Error:', error);
    });
   }
   }`

It's giving me this error in the console log

 Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.

I've also tried with the http.get<any>(mycode), but it doesn't accept a body I think, because of the error it gave me.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437

1 Answers1

-2

The be correct you should use query params or resource params for that. Here is few examples:

Query Params

this.httpClient.get(this.url, { params: {lookFor: matricola } })

Resource Params

this.httpClient.get(`${this.url}/${matricolaID}`)

To add extra headers, just add to the options object like

this.httpClient.get(this.url, { params: {lookFor: matricola }, headers: headers_object })

Here you can find a documentation: https://angular.io/api/common/http/HttpClient

Also in most IDE's you can open source code via clickin CMD+B (on mac), so you will get this:

enter image description here

If you really need add some body you can use http.request, so you will be able to add body to your GET request, but it may not work properly. Also, instead of adding JWT to the request, it's better practice to create an interceptor for that.

In angular DELETE is also not accepting body, but you can omit this with:

   this.httpClient.request('delete',`${configuration.apiServerUrl}/images`, {
      body: { url: imageUrl },
    });

You can do the same with get - but for chrome it will not pass. Here are docs: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET

   this.httpClient.request('GET','link-to-be', {
      body: { foo: bar },
    });
Wojciech Parys
  • 339
  • 2
  • 18
  • The APIs browsers provide for making HTTP requests do not allow GET requests to have a body. Changing the library function or library that wraps around the browser’s native functions wont’ change it. – Quentin Feb 02 '23 at 09:16
  • The [documentation](https://angular-doc.ru/api/common/http/HttpClient#request) says that the first parameter is the HTTP method. Your code is making a DELETE request, not a GET request. – Quentin Feb 02 '23 at 09:19
  • Disagree. GET allows to send a body. It's better to avoid that but it's not disallowed. There are many situations when you'll need body for GET request. – Wojciech Parys Feb 02 '23 at 09:39
  • My code is making a DELETE request, because as I said, it's an example. Which is more real-live scenario of using `request`. – Wojciech Parys Feb 02 '23 at 09:40
  • There are much better purposes of passing some params into get like query params or resource params. But question was how to send body via GET request, so here is the answer for that. – Wojciech Parys Feb 02 '23 at 09:42
  • "Disagree. GET allows to send a body. It's better to avoid that but it's not disallowed. There are many situations when you'll need body for GET request." — Either you're talking about in HTTP in general (where it is discouraged, but not disallowed, and some non-browser APIs support it) and are ignoring the bit where I talked about the underlying browser APIs which simply do not allow it *or* you're completely wrong. – Quentin Feb 02 '23 at 09:42
  • Added more detailed example – Wojciech Parys Feb 02 '23 at 09:51
  • @WojciechParys thanks, but what if i need to include also a token within the header of the GET? – juniorangulardeveloper Feb 02 '23 at 09:54
  • If you need for all request, It'll be much better if your write an interceptor for that. Here is a detailed article for that: https://dev-academy.com/how-to-use-angular-interceptors-to-manage-http-requests/ and NG documentation: https://angular.io/api/common/http/HttpInterceptor – Wojciech Parys Feb 02 '23 at 09:55
  • @juniorangulardeveloper for just one request I've added an example to the answer for you – Wojciech Parys Feb 02 '23 at 10:01
  • I found a sandbox project demonstrating making HTTP requests with angular, [forked it](https://codesandbox.io/s/learn-http-in-angular-forked-9xocfb?file=/src/app/people.service.ts), and replaced the code for making the GET request with yours (changing the URL and replacing `bar` with a number literal to avoid a reference error). Then I ran the code and monitored the request in the Network tab of my browsers developer tools. There was no request body. **Browsers will not let you add a request body to a GET request**. – Quentin Feb 02 '23 at 10:05
  • so I can't do that, right? – juniorangulardeveloper Feb 02 '23 at 10:08
  • @Quentin Not every browser will handle this, yes. @ juniorangulardeveloper for making this call you should use query params <- this is the proper usage – Wojciech Parys Feb 02 '23 at 10:13
  • @WojciechParys I think the request interception service solution might work, but the problem is that when I log in I make a 'POST' type call where I don't have the token defined yet, as I'm going to load it later in the localstorage , and this causes an undefined token error – juniorangulardeveloper Feb 02 '23 at 10:13
  • Sorry for bombarding you with questions, but I don't always understand what you're saying as I'm a rookie. – juniorangulardeveloper Feb 02 '23 at 10:14
  • Start with making a call with adding authentication to the headers. Next you can try refactor and use interceptor. In interceptor you can just create some statement to filter out non wanted urls. Then you can play with other refactors like moving it to some config options etc. Try with the simplest and check how it works. You do not need have it perfect at start ;) – Wojciech Parys Feb 02 '23 at 10:19
  • @WojciechParys — *Every* modern browser is consistent with dropping request bodies on GET requests. Also, it looks like the library you are using [drops bodies on GET requests](https://github.com/angular/angular/blob/2fc5b70fcedb8ac35b825b245c0ae394dc125244/packages/common/http/src/request.ts#L203) before it even gets to the underlying browser API. – Quentin Feb 02 '23 at 10:21
  • Can you give me an example of how to exclude for example the POST call I make for login if it doesn't bother you too much or takes up too much time?? This is the code I copied for the 'tokeninterceptor' service : https://dev-academy.com/how-to-use-angular-interceptors-to-manage-http-requests/ in the 'Basic authentication' section – juniorangulardeveloper Feb 02 '23 at 10:24
  • You can find the answer for that question here: https://stackoverflow.com/questions/55522320/angular-interceptor-exclude-specific-urls – Wojciech Parys Feb 02 '23 at 10:25
  • small update: Now the token is passed automatically, and it actually works for the calls I make before this famous get. However, when I get to the get whose syntax is this: return this.http.get(this.url, {params: {lookFor: serial number}}) it gives me the following error in the log: error : {error: 'Bad request: missing req.body.lookFor'} – juniorangulardeveloper Feb 02 '23 at 11:28
  • @WojciechParys can you help me with this? – juniorangulardeveloper Feb 02 '23 at 12:50