0

I have a javascript file in a server I can't modify.

Here is a sample of the script I have to download:

var tags = '';
tags += '<a href="#somelink"><img src="someimage.gif"/></a>;
document.write(tags);

I started downloading the script via AJAX and executing it, but I bumped into the "document.write cannot be executed in asynchronous call" problem.

So I wanted to download the script as a plain text and take what I need from the response and put it where it should go in my html page without modyfing the original script.

$.ajax({
    type: "GET",
    url: "http://myurlexample.com",
    dataType: "text",
}).success(function(msg){
    console && console.log("The script was downloaded as text: "+msg);
}).error(function(object,status,errortxt){
    console && console.log("The script wasn't downloaded as text. The error:"+ errortxt);
});

But AJAX throws an error when I do the download request using dataType = "text". Is there any way to go around this and actually download it as a text?

P.S: The script is for a Firefox OS privileged app, so I can't put the script directly in the html page because the security CSP doesn't allow it (https://developer.mozilla.org/en-US/Apps/CSP).

Mavi
  • 77
  • 1
  • 9
  • Can you add the code where you are actually making the Ajax call? And what is up with the script using `document.write`? – Matt Nov 15 '13 at 15:47
  • This worked for me on my site: `$.ajax({ url: "ascript.js", dataType: "text", success: function(script) { console.log(script); } });` – megawac Nov 15 '13 at 15:50
  • Matt: The problem with document.write in the asynchronous calls is that the script is not directly linked with the document directly, so it doesn't know where it should put the variable to write. I learned it from here: http://stackoverflow.com/questions/13003644/async-loading-javascript-with-document-write. Also, I added the part of the code that makes the call in the question – Mavi Nov 15 '13 at 16:03
  • I guess you're trying to reinvent the [JSONP](http://stackoverflow.com/questions/2067472/what-is-jsonp-all-about) here. If you don't have the possibility to modify the script to implement JSONP in it, make sure it isn't already there. – matewka Nov 15 '13 at 16:07
  • 1
    "But AJAX throws an error" — **What** error?! – Quentin Nov 15 '13 at 16:07
  • megawac: so I should try the call without the "type:'GET'" attribute? – Mavi Nov 15 '13 at 16:09
  • Quentin: I tried printing the error to the console but didn't get anything, just blank wich was very unusual – Mavi Nov 15 '13 at 16:12
  • @Mavi Based on [MDN's information on Firefox's packaged apps](https://wiki.mozilla.org/Apps/Security#Packaged_apps), all Ajax calls are considered cross-origin. You're being stopped by the same-origin policy, just as you would on any other web page trying to read a resource on another origin. – apsillers Nov 15 '13 at 16:15
  • Here is a link to a pic of the message in the Firefox console: https://dl.dropboxusercontent.com/u/18583165/programas/consola.png – Mavi Nov 15 '13 at 17:42
  • @apsillers I understand the same-origin policy, but I got around that problem by putting my app has a privileged app, asking for the systemXHR permission in my manifest and adding the line { mozSystem: true } every time I asked for a XMLHttpRequest just as explained here: [link](http://davidwalsh.name/forums/topic/firefox-os-systemxhr/) It works in my app for other requests that I made had successful results – Mavi Nov 15 '13 at 17:48

1 Answers1

1

Since you seem able to run the script successfully somehow, here's a terrible idea that might work: overwrite document.write.

Before you run the script, do:

document.write = function(msg) {
    handleTagStringInApp(msg);
    delete document.write; // revert to original document.write when done
};
// now load execute the script...

where handleTagStringInApp is a function you write that processes the tag string somehow. This is basicallyJSONP, but you can't adjust the callback name to be something unobtrusive or helpful and must instead use the callback name document.write.

Note that this will be really bad if anything else in your app actually needs to use document.write. (You might get around this in your own code by keeping a reference to the real document.write, e.g., using var realDocWrite = document.write; on page load and calling it with realDocWrite.call(document, "whatever").)

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • It worked!! Thankfully I hadn't used document.write in my app, so it didn't caused any problem and I retrieved the information I wanted from the script... I'll still be vigilant about the document.write in case I have to use it, by creating the reference just as you said. – Mavi Nov 15 '13 at 18:14
  • 1
    Based on your comments, I might suggest one possible alternative: try `jQuery.support.cors = true`. It's possible that the Firefox app environment causes jQuery to think that cross-domain requests are not allowed, so you can explicitly tell jQuery that they are allowed. – apsillers Nov 15 '13 at 18:59