Here's a little bit about content negotiation.

An HTTP client, such as your browser, or perhaps jQuery's ajax method, can set an Accept header as part of an HTTP request.

Accept Header

This header is meant to tell the server what content types it is willing to accept. From the HTTP 1.1 spec, section 14.1:

The Accept request-header field can be used to specify certain media types which are acceptable for the response.

Such a header might look something like this:

Accept: application/json

In a typical request from Chrome, we see something more like this:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

As you can see, the Accept header can get complex.

The above example lists a few media types the client (Chrome) is willing to accept, and even gives them a "quality" factor (the q rating, value 0-1). This is essentially telling the server the ordered preference of content types it wants back.

I won't get any more into that, but your can read more about it in the HTTP spec.

The Server

It's up to the server to follow the rules of HTTP. When a request comes to our application, it's pretty easy to ignore these rules, as our frameworks generally let us return whatever we want.

This is the "negotiation" part. The client says what content types it's willing to accept, and its preference. The server then can decide what it's willing/able to send back. Or ignore it, if it's a rebel. Not much of a negotiation, if you ask me.

For example, if a request comes into your Laravel app with an Accept header requesting JSON, you can totally ignore it without ever realizing the HTTP client wanted something else:

Route::get('/foo', function()
{
    // Accept header? Whatever, bruh
    return view('foo.bar');
});

Checking the Accept heade