Lame opening remarks

When we were asked about the difference between GET and POST in HTTP requests, many answers said that GET data must be sent through the URL as a Query Parameter, while POST can send data through the request body. Therefore, due to the limitation of URL, Often GET cannot send too many characters.

Can’t GET send data via Request Body?

No.

This idea is based on the fact that the method properties of web forms are only GET and POST.

Because method is set to POST, the form data is placed in the body, while method is get (the default), and the browser concatenates the form’s characters into the action URL and passes them as query parameters.

GET vs POST

This leads to the illusion that AN HTTP GET must send data through the query parameters of the URL.

The HTTP specification doesn’t say that GET can’t send body data. In RFC GET, it just says:

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.

It’s just that GET means to identify resources by URI.

Let the test talk!

test

After years of misunderstanding the difference between GET and POST, I suddenly realized that GET should be able to use body, and HTTP itself is a plain text protocol.

You can’t have 100% of your say without testing, so the following tests were done.

GET request API created in a Spring Boot Web project:

@RestControllerpublic class DemoController {    @RequestMapping(value = "/", method = RequestMethod.GET)    public String getRequest(@RequestParam("id") String id, @RequestBody String body) {        return id + ": " + body;    }}Copy the code

Create a GET request with the URL /? Id =something, and then you want to get the request data via the Request body.

1.Unit testing

For another test case, send the body data to the GET request:

@RunWith(SpringRunner.class)@WebMvcTestpublic class DemoControllerTest { @Autowired private MockMvc mockMvc; @Test public void shouldReturnDefaultMessage() throws Exception { this.mockMvc.perform(get("/? id=100").content("Hello, Get Body")) .andDo(print()) .andExpect(content().string(is("100: Hello, Get Body"))); }}Copy the code

The above unit test passed successfully, showing that we can also send data using Request Body for GET requests, and the Spring testing framework also supports GET sending Body data.

2,Curl call test

Delete from curl: delete from curl: delete from curl: delete from curl: delete from curl: delete from curl: delete from curl: delete from curl

curl

Curl -v indicates that the content-Length of each Request is 8. The content-Length of each Request is 8. The content-Length of each Request is 8.

3,Wireshark caught

The following are the packets captured using Wireshark:

Wireshark

Support for other tools

Using the Spring test case and curl command to send the body data, you can see that GET is used to send the body data.

But there are tools or libraries that don’t let us set the Body when we send a GET request.

1. Postman

As with the famous Postman, the Body tag is grayed out when selecting GET:

Postman

In addition, the Apache Http Client 4.5 component does not support setting Request Body because HttpGet does not have a setEntity(Entity) method like HttpPost.

2, OkHttpClient

The other OkHttpClient library also does not support GET sending Request Body when executing the following code:

new Request.Builder() .url("http://localhost:8080/? id=100") .method("GET", RequestBody.create(MediaType.parse("application/json"), "hello body")) .build();Copy the code

Just tell me:

java.lang.IllegalArgumentException: method GET must not have a request body

3, AsyncHttpClient

Finally try one more AsyncHttpClient library:

Dsl.asyncHttpClient() .prepareGet("http://localhost:8080/? id=100") .setBody("Get Body") .execute() .toCompletableFuture() .thenAccept(System.out::println).join();Copy the code

Output “100: Get Body” to prove AsyncHttpClient can send Body data on Get.

The subtotal

Neither Apache HttpClient nor OkHttpClient supports GET requests to send Body data, while AsyncHttpClient does.

So let’s go back and think about why HTTP doesn’t say you can’t send Body content in GET, but there are a lot of well-known tools that don’t send Body data in GET, so basically we still don’t recommend using GET to carry Body content. It is also possible that some application servers will ignore the Body data of GET. Guess).

I think it’s more that GET is designed to identify resources with urIs. If you let it carry data in the request body, then the usual caching service fails and the URI cannot be used as a cache Key.

On the other hand, if you need to send a large amount of data using the Body just to read the resource, switching to a POST request is incompatible with RESTFul POST semantics. It might be possible to GET + BODY at this point, but you can’t cache the request with the URI as the Key.

Reprinted from: https://yanbin.blog/why-http-get-cannot-sent-data-with-reuqest-body/ author: Songbird septum

END

This public account all blog posts have been sorted into a directory, please reply “1024” in the public account to obtain!

welfare
2018 
Dark horse Python, Java latest employment class video
2018

Share my Python learning resources

What is your most frequently used Linux command?

Python captures the knowledge planet essence and generates an ebook

The crawler little helper | automatic recording browser action to generate the Selenium script

Teach you to read web pages in Python

Python crawls “Planet of Knowledge”

Are you still using format to format strings?

Python to spin the Excel

If you feel good, pay attention to it and make progress together with me!

Your attention is my motivation to keep writing!