Open Bug 1143352 Opened 9 years ago Updated 2 years ago

Ajax XMLHttpRequest can only POST a max of 4K

Categories

(Core :: DOM: Core & HTML, defect)

36 Branch
x86
macOS
defect

Tracking

()

UNCONFIRMED

People

(Reporter: rpatri, Unassigned, NeedInfo)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36

Steps to reproduce:

HTML5 XHR2 ajax to do the File Upload. Using File API break up the file into 10MB chunks. The Ajax POST call fails if the chunk size is greater than 4096 Bytes.  Ajax POST request is not sent to the Server and does not go out of the Browser.

 This is only happening with version 36. Version 35 and 34 it works fine.

Steps:
var xhr = new XMLHttpRequest();
xhr.open("POST", someurl, true);
xhr.setRequestHeader('Content-Type', "application/octet-stream");
xhr.send(blob);	




Actual results:

XMLHttpRequest is not sent. The Firebug shows the request "Aborted" and Status code 0.



Expected results:

XMLHttpRequest should have been sent and expected HTTP code 200.
bug 793431 might be relevant, although it's more about loading, not sending.

bug 678648 suggests that XHR generally works with files up to 2GB.

You're splitting the data into chunks, but you don't say how you do it. Can you provide a testcase that can be used to reproduce the problem?
Component: Untriaged → DOM
Flags: needinfo?(rpatri)
Product: Firefox → Core
Thanks for the reply:

I use the HTML5 API to split the file into chunks:

var chunk = blob.slice(start, end);
	
if end - start > 4K it is not working in FF36.

The following does Ajax Post

var xhr = new XMLHttpRequest();
xhr.open("POST", turl, false);
xhr.setRequestHeader("CHUNK_INDEX", chindex);
xhr.setRequestHeader("OFFSET", offset);
xhr.setRequestHeader("LAST_CHUNK", lastChunk);
xhr.setRequestHeader('Content-Type', "application/octet-stream");
xhr.send(chunk);
Flags: needinfo?(rpatri)
Forgot to testcase to the comment:

To reproduce the issue in Firefox 36:

1). Create a file chunk large than 4K using HTML5 slice API 

var chunk = blob.slice(start, end);

start - start position of the file 
end - end position of the file


2) Post the chunk using Ajax.


Use firebug and it will show aborted and status code 0 when posting the chunk.
Could you post the complete working testcase, not just parts of it? (preferably with a public server endpoint.) The problem often is in the parts of code you didn't post :)
QA Whiteboard: [triaged]
Hi Dev Team,

The following is the way we are splitting the file into chuncks and do a transfer muti part ,which works fine in firefox older versions.
function uploadFile(blobFile, turl, offset, chindex, lastChunk) {

	//var fd = new FormData();
	//fd.append("files", blobFile);
	var xhr = new XMLHttpRequest();
	xhr.open("POST", turl, false);
	xhr.setRequestHeader("CHUNK_INDEX", chindex);
	xhr.setRequestHeader("OFFSET", offset);
	xhr.setRequestHeader("LAST_CHUNK", lastChunk);
	xhr.setRequestHeader('Content-Type', "application/octet-stream");
	xhr.send(blobFile);

}

self.onmessage = function(e) {
	var cal_per = 1;
	var data = e.data;
	var blob = data.file;
	var turl = data.url;
	var browser = data.browser;
	var firefox_blob = 4096;
	var others_blob =10485760;
	var sp = 0;
	const
	SIZE = blob.size;
	var start = 0;
	var end = 0;
	//console.log(browser);
	if(!browser)
	{
		//console.log(browser);
	if (blob.size < others_blob) {
		end = 1048576;
		sp = 1048576;
	} else {
		end = 10485760;
		sp = 10485760;
	}
	
	}
	else
	{
	if (blob.size < firefox_blob) {
		end = 4096;
		sp = 4096;
	} else {
		end = 4096;
		sp = 4096;
	}
  }
	var offset = 0;
	var chindex = 0;
	var lastChunk = 0;
	while (start < SIZE) {
		offset = start;
		var chunk = blob.slice(start, end);
		if (end == SIZE) {
			lastChunk = 1;
		}
		if (cal_per == 1)
			self.postMessage(cal_per);
		uploadFile(chunk, turl, offset, chindex, lastChunk);
		start = end;
		end = start + sp;
		chindex = chindex + 1;
		if (end < SIZE) {
			cal_per = ((start * 100) / SIZE);
		} else {
			cal_per = ((SIZE * 100) / SIZE);
		}
		if (cal_per > 1 && Math.round(cal_per) != 100)
			self.postMessage(cal_per);

	}
	self.postMessage(100);	
}

The following the way we are calling function.
"<%=request.getContextPath()%>"+"/rest/fileimport/transferMultipartFile?importId="+res;
This call would access our function and would spilt the responses as per message size.
But in latest Firefox version when the post size is more than 4 kb its keep aborting the Post requests and so response not reaching the back end.

The same code and scenario works fine all other browsers and older version of Firefox.so we modified our request for latest version of Firefox by sending 4 kb chunks.
None of that answers the request in comment 4.

This generally works, so something special is going on in your particular setup.  If you don't have a way to give someone else access to that setup to try reproducing the problem, are you willing to use http://mozilla.github.io/mozregression/ to figure out when the problem first appears?  That would at least give us _something_ to go on.
Flags: needinfo?(sivasathy27)
Flags: needinfo?(rpatri)
Component: DOM → DOM: Core & HTML
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.