This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the web-development category.
Last Updated: 2024-11-23
I uploaded a static website to s3 but it had a problem. When I visited the
index.html
file in Chrome, the file was downloaded instead of rendered.
Inspecting the HTML headers, its Content-Type was wrong: Instead of 'text/html'
it was "Content-Type: binary/octet-stream". Thus the downloading. The fix was to
set the content-type when uploading the object to s3.
I installed DebugBar
into some PHP code. To my surprise, this broke
various client-side JavaScript endpoints in development. This is because these
endpoints expected data in JSON or XML formats and then parsed them client-side.
However, DebugBar
appends itself to the output from the server. This sorta
makes sense, since where else could it possibly appear, it being an
exclusively backend-installed tool?
I looked into the DebugBar
features, and it knows to hide itself when it's a
JSON or XML content-type. My current JavaScript code specified nothing about
Content-Type (I was trying to be economical) so therefore the hiding was not
triggered during my XML/JSON requests.
After specifying the Content-Type headers for these requests, everything worked.
JSON post APIs often require two application/json
entries: Content-Type
and Accept
I had the following code:
def get(url)
...
request = Net::HTTP::Get.new(url)
# Important bit:
request['accept'] = 'application/json'
request['api-key'] = api_key
response = http.request(request)
parse_response_as_json(response)
end
def post(url, data = {})
...
request = Net::HTTP::Post.new(url)
# Important bit:
request['accept'] = 'application/json'
request['api-key'] = api_key
request.body = data.to_json
response = http.request(request)
parse_response_as_json(response)
end
The get
method worked but the post
returned error 406 - "not acceptable"
This was confusing because the methods seemed symmetrical. In reality, what was missing was the "content-type" header for the POST method. Here's the fix
...
request['accept'] = 'application/json'
request['content-type'] = 'application/json'
The reason this is needed is in order for the server to know how to deal with the payload.
Note a potential confusion here: both GET and POST responses from the server will have a content type. However POST requests also have one, since the payload may be significant in size.
Always set content-type headers for requests