Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox is parsing empty response payload

We're making an XHR request with the following headers (I've simplified a bit):

POST http://localhost:9001/login

Host: localhost:9001
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=utf-8
Content-Length: 67

Then our server responds like this (again simplified):

Status code: 200 OK

Cache-Control: no-cache, no-store
Connection: close
Content-Length: 0
Date: Mon, 27 Feb 2017 17:19:53 GMT
Server: WildFly/9
Set-Cookie: JSESSIONID=123; path=/

There's no payload in the response. Note the Content-Length: 0. But Firefox still tries to parse it as XML. And outputs the following error to the console:

XML Parsing Error: no root element found 
Location: http://localhost:9001/login 
Line Number 1, Column 1

Note, the server doesn't send a content-type header. And according to RFC 7231 it only has to send a content-type header when there is actual content.

So is this a bug in Firefox or is my research faulty?

Reproducing it yourself

I've written a small server and client to reproduce the problem.

server.js (start with node ./server.js):

const fs = require('fs'), http = require('http');
const server = http.createServer(function (request, response) {
    if (request.method === 'POST') {
        // send empty response
        response.end();
        return;
    }

    // send file content
    fs.readFile('.' + request.url, function (error, content) {
        response.writeHead(200, { 'Content-Type': request.url === '/index.html' ? 'text/html' : 'text/javascript' });
        response.end(content);
    });
}).listen(8080);

index.html

<script src="client.js"></script>

client.js

var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/login');
xhr.send();

When opening the URL http://localhost:8080/index.html in Firefox, there will be an error in the JavaScript console.

Firefox Version 51.0.1

like image 515
Sebastian Häni Avatar asked Feb 27 '17 17:02

Sebastian Häni


1 Answers

There's no payload in the response. Note the Content-Length: 0

That means there is a payload, and that payload is 0 bytes in size. Consider the difference between null and "" as strings. What you have here is the equivalent of "" when you want the equivalent of null.

Set the status code to 204 rather than 200 to indicate you aren't sending an entity (and remove the content-type, since there's no content-type with no entity).

(For a long time Firefox would still log an error for this case, but thankfully this is finally fixed. Even when it did log the error it would still continue to run any scripts correctly).

like image 58
Jon Hanna Avatar answered Oct 14 '22 13:10

Jon Hanna