Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I change the headers of the HTTP request sent by the browser?

I'm looking into a restful design and would like to use the HTTP methods (POST, GET, ...) and HTTP headers as much as possible. I already found out that the HTTP methods PUT and DELETE are not supported from the browser.

Now I'm looking to get different representations of the same resource and would like to do this by changing the Accept header of the request. Depending on this Accept header, the server can serve a different view on the same resource.

Problem is that I didn't find a way to tell my browser to change this header.

The <a..> tag has a type attribute, that can have a mime type, looked like a good candidate but the header was still the browser default (in Firefox it can be changed in about:config with the network.http.accept.default key).

like image 572
Jeroen Wyseur Avatar asked Dec 17 '08 15:12

Jeroen Wyseur


3 Answers

I would partially disagree with Milan's suggestion of embedding the requested representation in the URI.

If anyhow possible, URIs should only be used for addressing resources and not for tunneling HTTP methods/verbs. Eventually, specific business action (edit, lock, etc.) could be embedded in the URI if create (POST) or update (PUT) alone do not serve the purpose:

POST http://shonzilla.com/orders/08/165;edit

In the case of requesting a particular representation in URI you would need to disrupt your URI design eventually making it uglier, mixing two distinct REST concepts in the same place (i.e. URI) and making it harder to generically process requests on the server-side. What Milan is suggesting and many are doing the same, incl. Flickr, is exactly this.

Instead, a more RESTful approach would be using a separate place to encode preferred representation by using Accept HTTP header which is used for content negotiation where client tells to the server which content types it can handle/process and server tries to fulfill client's request. This approach is a part of HTTP 1.1 standard, software compliant and supported by web browsers as well.

Compare this:

GET /orders/08/165.xml HTTP/1.1
or
GET /orders/08/165&format=xml HTTP/1.1

to this:

GET /orders/08/165 HTTP/1.1
Accept: application/xml

From a web browser you can request any content type by using setRequestHeader method of XMLHttpRequest object. For example:

function getOrder(year, yearlyOrderId, contentType) {
 var client = new XMLHttpRequest();
 client.open("GET", "/order/" + year + "/" + yearlyOrderId);
 client.setRequestHeader("Accept", contentType);
 client.send(orderDetails);
}

To sum it up: the address, i.e. the URI of a resource should be independent of its representation and XMLHttpRequest.setRequestHeader method allows you to request any representation using the Accept HTTP header.

Cheers!
Shonzilla

like image 145
Shonzilla Avatar answered Oct 19 '22 17:10

Shonzilla


I was looking to do exactly the same thing (RESTful web service), and I stumbled upon this firefox addon, which lets you modify the accept headers (actually, any request headers) for requests. It works perfectly.

https://addons.mozilla.org/en-US/firefox/addon/967/

like image 12
Chris Avatar answered Oct 19 '22 16:10

Chris


I don't think it's possible to do it in the way you are trying to do it.

Indication of the accepted data format is usually done through adding the extension to the resource name. So, if you have resource like

/resources/resource

and GET /resources/resource returns its HTML representation, to indicate that you want its XML representation instead, you can use following pattern:

/resources/resource.xml

You have to do the accepted content type determination magic on the server side, then.

Or use Javascript as James suggests.

like image 8
Milan Novota Avatar answered Oct 19 '22 16:10

Milan Novota