Amblem
Furkan Baytekin

JSON Sent as text/plain

Master API response parsing by checking Content-Type headers first

JSON Sent as text/plain
87
4 minutes

Once, I was working on a project at my company. There was a requirement to extract a single key from a JSON response coming from a backend API and use it in a redirect URL. Android and iOS developers used the same endpoint and completed their part without issues. But the web app I was building didn’t work.

I checked the response model. I was expecting a JSON object—but what I got wasn’t JSON at all. Or so I thought.

I dug into it and opened the Swagger docs. Turns out, the response was valid JSON—but the Content-Type was set to "text/plain" instead of "application/json". I asked the mobile devs how they handled it. They said they always parse the response manually, regardless of the Content-Type.

But in the frontend world, we don’t just JSON.parse() everything. We rely on the response headers to determine the format. If the header says it’s plain text, we treat it as plain text.

I begged the backend dev to change the Content-Type to "application/json"—and they did.


When & How to Parse API Responses

APIs can return responses in many formats: JSON, XML, HTML, plain text, SGML, etc. You must not assume the format based on the content. Always check the Content-Type header first.

Here’s a simple guide:

Content-Type Description
application/json JSON data
application/xml XML data
text/plain Plain text
text/html HTML content
text/sgml SGML content

All the following examples are meant to be used inside async functions, since most fetch methods return Promises.


✅ JSON

If Content-Type is not application/json, do not treat the response as JSON.

json
{ "name": "John", "age": 30 }
javascript
const response = await fetch('https://api.example.com/data'); const contentType = response.headers.get('Content-Type'); if (contentType && contentType.includes('application/json')) { const data = await response.json(); console.log(data.name); // John }

✅ XML

Client-side:

xml
<note> <to>Furkan</to> <from>ChatGPT</from> <message>Hello!</message> </note>
javascript
const response = await fetch('https://api.example.com/data'); const text = await response.text(); const parser = new DOMParser(); const xmlDoc = parser.parseFromString(text, "application/xml"); const to = xmlDoc.getElementsByTagName("to")[0].textContent; console.log(to); // Furkan

Server-side (Node.js):

javascript
const xml2js = require('xml2js'); const response = await fetch('https://api.example.com/data'); const text = await response.text(); xml2js.parseString(text, (err, result) => { if (err) throw err; console.log(result.note.to[0]); // Furkan });

✅ HTML

html
<p>Hello!</p> <figure> <img src="https://example.com/image.jpg" alt="Example Image"> <figcaption>Example Image</figcaption> </figure> <p>This is an example article.</p>

We assume there’s an <article> element in the DOM and insert the content there:

javascript
const response = await fetch('https://api.example.com/html'); const htmlDoc = await response.text(); const article = document.querySelector('article'); article.innerHTML = htmlDoc;

✅ Plain Text

text
You've got mail!
javascript
const response = await fetch('https://api.example.com/message'); const text = await response.text(); const box = document.getElementById('message-box'); box.textContent = text;

✅ SGML

SGML is rare on the web today. But if the server sends Content-Type: text/sgml, it should be parsed accordingly.

Example content:

sgml
<!DOCTYPE note SYSTEM "note.dtd"> <note> <to>Furkan</to> <from>ChatGPT</from> <message>Hello!</message> </note>

There’s no native browser support for parsing SGML, so you’d need a third-party parser on the server side. This example is illustrative only:

javascript
const sgml2js = require('sgml2js'); const response = await fetch('https://api.example.com/sgml'); const sgmlText = await response.text(); const sgmlDoc = sgml2js.parse(sgmlText); console.log(sgmlDoc.note.to[0]); // Furkan

🔚 Conclusion

Never parse a response without checking its Content-Type first. That header tells you how to treat the body.

If you want to parse the response as a certain format, make sure the backend sends the correct content type. Otherwise, you’re just guessing—and your app might break silently.


Album of the day:

Suggested Blog Posts