"not well-formed" error in Firefox when loading JSON file with XMLHttpRequest
Asked Answered
P

9

71

I'm getting a "not well-formed" error in the error console of Firefox 3.0.7 when the JavaScript on my page loads a text file containing an object in JavaScript Object Notation format. If the file contains nothing but the JSON object, it produces the error. If I wrap the object in <document></document> tags it does not produce the error. The request succeeds either way, so I could just ignore it, but I don't want my error log filling up with these messages.

Here is some example code to illustrate the problem. First, the "not well-formed" file called "data.json":

{ a: 3 }

Now some code to load the file:

var req = new XMLHttpRequest();
req.open("GET", "data.json");
req.send(null);

Which produces the following error in the Firefox error console:

not well-formed
file://path/to/data.json Line: 1
{ a: 3 }
- ^

If data.json is modified to this:

<document>{ a: 3 }</document>

There is no error. I assumed that it is complaining because the plain JSON file is not a well formed XML document, so I tried overriding the MIME type before the "send" call to force it to load as plain text, but that didn't work.

var req = new XMLHttpRequest();
req.open("GET", "data.json");
req.overrideMimeType("text/plain");
req.send(null);
// Still produces an error!

I am going to continue with wrapping my JSON data in an XML document to get around whatever validation the XMLHttpRequest is performing, but I'd like to know if there is any way I can force it to just load plain text uncritically and not try to validate it. Alternatively, is there another method of loading data besides XMLHttpRequest that can be used with plain text?

Pleuropneumonia answered 24/3, 2009 at 15:25 Comment(0)
S
77

Have you tried using the MIME type for JSON?

application/json

You could also configure your server to send this MIME type automatically for .json files.

Sverre answered 24/3, 2009 at 15:32 Comment(3)
To be more specific: req.overrideMimeType("application/json"); req.send(null); works. Specifying the MIME type in the server would be the better solution, but overriding it works as well.Pleuropneumonia
Where should this be placed? In the JSON file?Rambo
Is it possible to have such a solution when developping in local?Chardin
I
21

Firstly, true JSON is much stricter than JavaScript, and to be valid JSON, you have to have your keys quoted.

 { "a": 3 } 

Also, as you are using a bare XMLHttpRequest, which generally expects to receive an XML result unless MIME headers specify strictly otherwise.

You may however wish to make your own life easier by simply using a JavaScript framework such as jQuery which will abstract away all this problem for you and deal with all the nasty edge cases.

$.getJSON("data.json",{}, function( data ){ 
  /*  # do stuff here  */ 
});

Additionally, if you use both strict JSON and use a library to abstract it for you, when browsers start having native JSON parsers the library will be able to transparently make use of these and get a significant speed improvement.

( This is slated to happen sooner than later, and when it happens, your users will get a silent upgrade with no effort required! ).

Impede answered 24/3, 2009 at 15:33 Comment(6)
Thanks for the pointers on JSON. I will change my data to use quoted string attribute names. Unfortunately, jQuery, or some other framework, is not an option for me.Pleuropneumonia
I'd be most interested why, generally that's the sign of code-stink to vehemently avoid code reuse and to avoid using solved problems.Impede
@Kent, I'd be happy to use jQuery. However, the approval process for using jQuery is prohibitively difficult. The amount of time it would take to argue with the customer and demonstrate that we need to use jQuery is not worth the benefit. Sad, but true.Pleuropneumonia
@A. Levy: you'll learn, and next time you'll be less likely to hand-code-everything :)Impede
using $.getJSON() still generates that error message for me.Gariepy
@Shoosh , are you encoding your data properly? As stated, you MUST encode keys and values appropriately, see jsfiddle.net/kentnl/uGDQP/1 for examples.Impede
A
7

This also occurs when Content-Type is completely empty (thereby circumventing the natural type-detection).

Apothegm answered 2/11, 2010 at 19:12 Comment(0)
R
4

It should be {"a": 3} actually.

Rustproof answered 24/3, 2009 at 15:33 Comment(0)
M
4

I found the same error message but from a very different cause. After a little time fruitlessly changing the JSON content, realized that I had accidentally restarted the page running off the local file system (file://Users/me/Sites/mypage.html) rather than the server (http://localhost/~me/Sites/mypage.html).

Minor answered 9/4, 2012 at 13:39 Comment(0)
K
0

I was also getting the same warning message with XMLHttpRequest() (in FireFox), when requesting resources marked as Content-Type: application/json by the server.

What did the trick for me was to explicitly set the XMLHttpRequest.responseType property to json on the request object. E.g,

var request = new XMLHttpRequest();
request.onreadystatechange = function() { ... }
...
request.open('GET','https://random-domain.com/random-path',true);
request.responseType = 'json';
...
request.send();
Kilovoltampere answered 20/9, 2016 at 22:58 Comment(0)
P
0
Browser --- request expects a given content-type ---> Server
        <-- response contains content-type ----------

Firefox looks at the HTTP Content-Type header. If the server HTTP response header does not match the expectations of your browser code it will complain with this message.

IMHO this error message could have been a lot better, like "Expecting response Content-Type header ... but found ...".

Pachydermatous answered 12/10, 2017 at 9:34 Comment(0)
C
0

Unless there is a specific reason for opening your HTML directly from the disk (file://), you should do yourself a favor and open it served by a local HTTP server (http://), like the prototype user has written. This will fix this issue because the MIME type will be set correctly, as jthompson suggested.

Thanks to that you will also not run into another issue, like "Reason: CORS request not HTTP", and possibly others as browsers are getting more and more suspicious when they are asked to open files on the local disk - and for good reasons (security!).


If you have Python on your system then the (arguably) easiest way to run a local HTTP server is:

Mac/Linux: python3 -m http.server

Windows: python -m http.server or py -3 -m http.server

The files from the current working directory will then be served under http://localhost:8000/

Confucianism answered 15/10, 2021 at 9:58 Comment(0)
D
-6

Kent, I disagree.

The following IS "valid" JSON:

{ a: 3 }

JavaScript object property names do NOT have to be strings.

The problem is one of MIME type, not JSON/JavaScript syntax.

I just solved this very issue by adding json as "text/javascript" to my webserver mime types file:

text/javascript                 js, json

The "not well-formed" error disappeared. The browser (FireFox) assumed, incorrectly, that the .json file was XML.

Digitoxin answered 24/11, 2010 at 7:23 Comment(5)
Wrong. It is valid javascript, and if you interpret it as javascript, then it will be fine. Howver, JSON is stricter than javascript, and the JSON format is parsed seperatly by a conformant client thant wants "JSON" not "Javascript". Any Specificiation compatible JSON parser treats unquoted keys as an error.Impede
To reiterate, JSON is a sublanguage of javascript, and while ALL JSON is valid javascript, NOT all Javascript is valid JSON.Impede
If you disagree with me, take your complaint to Mozilla, as you're arguing their JSON parser is wrong =). jsfiddle.net/kentnl/uGDQPImpede
I have to say that requiring keys to have "" is a mayor flaw in JSON. It's extra slump, JS proves it isn't required. It's probably there to accomodate parser writers, and there's far less parser writers than there's users. I also take grief of not being able to pass functions, but that at least makes sense.Briareus
Also the name "JavaScript Object Notation" is misguiding. It isn't the same notation as used in Javascript.Briareus

© 2022 - 2024 — McMap. All rights reserved.