I spent a day trying to figure out what’s wrong with the gibberish return in browser from my Flask API server. Interesting enough, I have other endpoints that work just fine, but not this new route I’ve just added. Here’s what I’ve come to learn to fix the issue.
Finding out the what’s the cause
I learnt that there are three major reasons that cause this.
- Content-Type – charset isn’t set to UTF-8, or it is not even being perceived as JSON
- Content-Encoding – Browser default auto compression for JSON has conflicts with the API encoding method.
Two ways to check it
cURL
Open your Terminal and use cURL
curl -v "https://yourdomain.com/endpoint?"
If the JSON is correctly shown, it means it is most likely the browser causing the issue.
If it is showing gibberish, make sure you have the charset to UTF-8 in the Flask app. Because it means it is not about the transmission that causes the issue, it was fundamentally not handling right within the Flask, and it could an object type/encoding issue.
Dev tool in the browser
- Go to the Network tab and refresh your endpoint page
- Check the Content-Type is ‘application/json; charset=UTF-8’
Solutions
Content-Type
If either application/json or charset=UTF-8 is missing, add the following response.header to your Flask API app for your endpoint:
response.headers['Content-Type'] = 'application/json; charset=UTF-8'
Now, restart the app and try again and see if it works. If not, proceed to the next step.
Content-Encoding
Now, you’ve made sure Content-Type isn’t the issue, as it shows correctly as application/json; charset=UTF-8. Let’s continue on the second cause – encoding error.
By default, when a Flask API sending a response to the browser, it will auto compress the content. And then, the browser will try to decode it. However, for some reason it can’t decode it right.
The perfect example would be cURL -v is getting correct response but in the browser it is gibberish. (This is my case.) cURL by default doesn’t receive a compressed/encoded response, that’s why it works in cURL but not in the browser.
To fix it, you’ll have to add following in your Flask API app response:
response.headers['Content-Encoding'] = 'identity'
This will disable compression by default, so your browser can get what cURL is getting.
That should fix it.
Good luck.