I have a very simple function that downloads chunks of a file using an xhr request that looks like so:
var blobXHR = new XMLHttpRequest();
//api.media.chunkURL() returns the correct URL for each chunk
blobXHR.open("GET", api.media.chunkURL({
fileId: fileID,
chunkId: chunkNumber
}));
blobXHR.responseType = "arraybuffer";
blobXHR.onerror = function (e) {
console.log("Error: ", e);
};
var arrayBuffer;
blobXHR.onload = function (e) {
arrayBuffer = blobXHR.response;
};
blobXHR.send();
Now this download function works without any hitches at all using Chrome, Firefox, and just about every Android browser. Unfortunately, when using anything Safari or iOS based I get a very vague error in blobXHR.onerror(). When I output this error to the console I get this response under "e.currentTarget.responseText":
Error: InvalidStateError: DOM Exception 11
I've looked up many questions similar to this and nothing has seemed to work. Any reason why I would be experiencing this with only Safari/iOS browsers?
Edit: This is what I get when I console.log(blobXHR) within onerror():
This is likely a CORS issue. Make sure your server is properly configured to allow this:
http://enable-cors.org/server.html
Also be mindful that Safari won't allow localhost for CORS.
Related
I tested the loading of very large files with XMLHttpRequest and noticed an interesting behavior of Chrome (90.0.4430.212): It loads the full file, but finishes with a 200-OK code and and empty (!) result. First I thought it was a silent timeout or whatever, but no, it seems to be a reached memory limit.
Trying it in Firefox (13.0esr (64-bit)) took for ages, but in the end I knew more: The Transfer itself did not trigger an "error" or a "timeout" event, resulted with 200 and empty result as well. But it threw an error:
Exception { name: "NS_ERROR_OUT_OF_MEMORY", message: "", result: 2147942414, filename: "http://localhost/testcenter-backend/vo_data/teterei.html", lineNumber: 16, columnNumber: 0, data: null, stack: "transferComplete#http://localhost/testcenter-backend/vo_data/teterei.html:16:9\n" }
So it has nothing to do with the transport itself, but apparently a memory limit reached when trying to do anything with the result. When I don't use the oReq.response, the error does not appear.
Okay, how to handle this? In Firefox I can catch the error with a simple try catch block. But this does not work for Chrome. A naive approach would be just to check if the resulting content is empty, but I wonder if there is another possibility to detect this stuff happening.
--
How to reproduce:
Create a huge file.
I generated a 10,4GB file this way:
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10000]
Run this code in a browser to load it.
const oReq = new XMLHttpRequest();
function updateProgress (oEvent) {
console.log("progress", oEvent.loaded);
}
function transferComplete(evt) {
console.log("The transfer is complete.", oReq.getAllResponseHeaders(), oReq.status);
console.log(oReq.response); // here too much memory is allocated
}
function transferFailed(evt) {
console.log("error", oReq.getAllResponseHeaders(), oReq.status);
}
function transferCanceled(evt) {
console.log("cancel", oReq.getAllResponseHeaders(), oReq.status);
}
function timeOut(evt) {
console.log("timeout", oReq.getAllResponseHeaders(), oReq.status);
}
oReq.addEventListener("progress", updateProgress);
oReq.addEventListener("load", transferComplete);
oReq.addEventListener("error", transferFailed);
oReq.addEventListener("abort", transferCanceled);
oReq.addEventListener("timeout", timeOut);
// your huge file here instead
oReq.open("GET", "https://cdn.jsdelivr.net/npm/jquery#3.2.1/dist/jquery.min.js"); // URL to huge file here
oReq.send();
The actual memory limit may vary to your system.
I'm trying to run "inherited" code and since I'm fairly new to HTML & javascript I keep running into annoying little issues (that's how you learn :D ).
I have a GET request that is meant to load an mp4 file from a server, but for the sake of debugging and practice, I'm trying to load it from a local directory. I enabled the "--allow-file-access-from-files" flag on my chrome, so I know it's not a SOP issue. I can't figure out why, the request is sent 3 times, ALWAYS the first and last fail and the 2nd doesn't, but the file is not loaded.
here's a simplified version of the code:
var req = new XMLHttpRequest();
req.open('GET', currentFileName, true);
// currentFileName is an mp4 in the same directory
req.responseType = 'blob';
req.onload = function () {
// Onload is triggered even on 404
// so we need to check the status code
if (this.status === 200) {
console.log("success!");
doSomeFunc();
}
}
};
req.send();
here's the network log:
I looked into many possible solutions (example 1, 2, 3, 4, 5)
Couldn't find a question where this happens with local files.
What might be wrong?
I get this error in Chrome immediately after reading a JSON file. It works correctly in Safari and Firefox.
console.log ("event -> "+ postcards.nodes[0].node.event); // "tally" in Safari "TypeError: Cannot read property 'node' of undefined" in Chrome.<
Is there a limit to the levels in a nested JSON file? I generate the JSON from a Drupal view. Here here is the start:
{"nodes":[{"node":{"w1":"","w2":"1","w3":"","w4":"", ...<
Here is the Javascript:
d3.json(
"/sites/default/d3_files/json/toronto-wards.json",
function(error,wards) {
d3.json("/postcards-json", function(error, postcards) {
console.log ("event -> "+ postcards.nodes[0].node.event); // tally in Safari
I'm using macOS and my friends using Windows get the same error in Firefox.
As per request here is what I think is the XHR message:
d3.min.js:1 XHR finished loading: GET "http://www.stopplastics.ca/postcards-json".
Does the following work for you?
Promise.all(
d3.json("/sites/default/d3_files/json/toronto-wards.json"),
d3.json("/postcards-json")
)
.then(
function([wards,postcards]) {
console.log ("event -> "+ postcards.nodes[0].node.event); // tally in Safari
Some browsers may not support deconstructing arrays so probably better to try the following for older browsers (non Chrome and Firefox):
Promise.all(
d3.json("/sites/default/d3_files/json/toronto-wards.json"),
d3.json("/postcards-json")
)
.then(
function(results) {
var wards=results[0],postcards=results[1];
console.log ("event -> "+ postcards.nodes[0].node.event);
}
);
According to the comments your drupal end point providing the JSON needs authentication so gives you empty data when you're not loged in.
Error has maybe nothing to do with the browser used but depends if you're loged in or not.
The problem was caused by the Drupal view not being created correctly. Nothing to do with the Chrome browser.
The following javascript function works fine for IE, Safari and Firefox. But it fails in Chrome(33.0.) and Opera (16.0.1196). Blank HTML page is displayed on loading.
function readTestXMLFile() {
if (window.ActiveXObject) {
var xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
xmlDoc.async = 'false';
xmlDoc.load('test.xml');
}
else {
var requ = new XMLHttpRequest();
alert("a");
requ.open("GET", "test.xml", false);
alert("b");
requ.send(null); //This line is not working in chrome and opera
alert("c");
var xmlDoc = requ.responseXML;
alert(xmlDoc);
alert("d");
}
return xmlDoc;
}
Only 'a' and 'b' gets printed. It does not continue after that. Same result is observed if I use requ.send() or requ.send("") instead of requ.send(null).
If I remove the statement requ.send(null), then 'null' value is printed for xmlDoc. Still blank HTML loads.
Please let me know what is the right way to get this work on Chrome and Opera.
Thanks
SRB.
Your error message suggest that you are trying to access a local file which is treated as "Cross origin request" if you try and run local server it should work.
Take a look at this previously asked question with the same problem:
Cross origin requests are only supported for HTTP but it's not cross-domain
Then you would access http://localhost/.../test.xml instead of c:/localhost/.../test.xml
You can also set a flag for Chrome to allow local files to request local files: -allow-file-access-from-files
the call to the XMLHttpRequest.send method is Asynchronous so you need to modify the call a little bit. The modified code below will print the response content when the response is returned successfully:
requ.addEventListener("load", function(e) {
alert(req.responseText);
}, false)
requ.send(null);
Update:
I didn't notice that you made the send request call synchronous.
Edit
You need to launch chrome with this parameter to be able to access local files
--allow-file-access-from-files
ex: c:\Browser\chrome.exe --allow-file-access-from-files
I think that the problem is that you're passing null to the send() method. You are making a GET request, so you should call send without parameters. I think chrome throws an exception because of that. Just remove the null
I am using the following code to read the xml file from JS
function ReadFile(xmlPath) {
oxmlhttp = null;
try {
// Firefox, Chrome, etc... Browsers
oxmlhttp = new XMLHttpRequest();
oxmlhttp.overrideMimeType("text/xml");
} catch (e) {
try {
// IE Browser
oxmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
return null;
}
}
if (!oxmlhttp) return null;
try {
oxmlhttp.open("GET", xmlPath, false);
oxmlhttp.send(null);
} catch (e) {
return null;
}
var xmlDoc = oxmlhttp.responseXML.documentElement;
alert(xmlDoc);
return oxmlhttp.responseText;
}
It's working fine for IE and Firefox but not in Chrome. the following exception "XMLHttpRequest cannot load the file. Cross origin requests are only supported for HTTP." should occur when i use chrome.
Can anybody know how to read the xml file in chrome using JS?
According to the error, there is some problem with the request domain. You shold alert the domain address of the request:
...
try {
alert(xmlPath) //alerting
oxmlhttp.open("GET", xmlPath, false);
oxmlhttp.send(null);
} catch (e) {
return null;
}
...
and the xmlPath sould not contain and another domain address.
read this issue aboute this: Cross domain Ajax request from within js file
Are you serving the xml file, or are you making tests using your file system ?
If you're using the file system, I'd recommend starting a small HTTP server on your site dir instead.
You can easily start a HTTP server to serve a directory, e.g. serve the current directory with Python:
$ python -m SimpleHTTPServer
Or if you're using Windows, maybe you'll like HFS better for the same purpose: http://www.rejetto.com/hfs/
Cheers!