PDA

View Full Version : [CLOSED] Upload completed and Chrome



paulc
Sep 25, 2013, 8:59 AM
Hi Guys,

I have a situation where I am not getting file upload completed events fired using Chrome. I think the reason is that Chrome doesn't raised an exception on cross domain issues but logs a message and returns a null object instead. Looking at the code that handles this means that the case falls through and neither a success or failure result is obtained...



try {
doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document;
// Opera will fire an extraneous load event on about:blank
// We want to ignore this since the load event will be fired twice

if (doc) {
if (Ext.isOpera && doc.location == 'about:blank') {
return;
}
if (doc.body) {


// Response sent as Content-Type: text/json or text/plain. Browser will embed in a <pre> element
// Note: The statement below tests the result of an assignment.
if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {
response.responseText = contentNode.textContent;
}


// Response sent as Content-Type: text/html. We must still support JSON response wrapped in textarea.
// Note: The statement below tests the result of an assignment.
else if ((contentNode = doc.getElementsByTagName('textarea')[0])) {
response.responseText = contentNode.value;
}
// Response sent as Content-Type: text/html with no wrapping. Scrape JSON response out of text
else {
response.responseText = doc.body.textContent || doc.body.innerText;
}
}
//in IE the document may still have a body even if returns XML.
response.responseXML = doc.XMLDocument || doc;
callback = options.success;
success = true;
}
} catch (e) {
// Report any error in the message property
response.responseText = '{success:false,message:"' + Ext.String.trim(e.message || e.description) + '"}';
callback = options.failure;
success = false;
}




What I need to do is to override this code somehow, so it checks for a null doc reference..

For Example...





try {
doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document;
// Opera will fire an extraneous load event on about:blank
// We want to ignore this since the load event will be fired twice





if (doc == null) {
throw('null reference');
}

if (doc) {
if (Ext.isOpera && doc.location == 'about:blank') {
return;
}
if (doc.body) {


// Response sent as Content-Type: text/json or text/plain. Browser will embed in a <pre> element
// Note: The statement below tests the result of an assignment.
if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {
response.responseText = contentNode.textContent;
}


// Response sent as Content-Type: text/html. We must still support JSON response wrapped in textarea.
// Note: The statement below tests the result of an assignment.
else if ((contentNode = doc.getElementsByTagName('textarea')[0])) {
response.responseText = contentNode.value;
}
// Response sent as Content-Type: text/html with no wrapping. Scrape JSON response out of text
else {
response.responseText = doc.body.textContent || doc.body.innerText;
}
}
//in IE the document may still have a body even if returns XML.
response.responseXML = doc.XMLDocument || doc;
callback = options.success;
success = true;
}
} catch (e) {
// Report any error in the message property
response.responseText = '{success:false,message:"' + Ext.String.trim(e.message || e.description) + '"}';
callback = options.failure;
success = false;
}




Problem is, I have no idea how to properly override this code? Can you help?

Daniil
Sep 25, 2013, 12:27 PM
Hi @paulc,

This should work.

Ext.data.Connection.override({
onUploadComplete: function (frame, options) {
/* the overrode code follows here */
}
});

You should put this override into the page's <head>.

paulc
Sep 26, 2013, 11:16 AM
OK thanks, yes that is working. I think the underlying issue is that the iframe is created with a url of "about:blank" but in Chrome his uses the protocol and host of the current window which is different to the host that is receiving the file. Do you know if there is a config value or way to set the host for the default iframe url?

Daniil
Sep 26, 2013, 2:11 PM
Please clarify are you uploading a file via FormPanel submit?

If so, an iframe for uploading is created in Ext.data.Connection's doFormUpload:

doFormUpload : function(o, ps, url){
var id = Ext.id(),
doc = document,
frame = doc.createElement('iframe'),
form = Ext.getDom(o.form),
hiddens = [],
hd,
encoding = 'multipart/form-data',
buf = {
target: form.target,
method: form.method,
encoding: form.encoding,
enctype: form.enctype,
action: form.action
};


Ext.fly(frame).set({
id: id,
name: id,
cls: 'x-hidden',
src: Ext.SSL_SECURE_URL
});

You can see this option:

src: Ext.SSL_SECURE_URL

So, by default the URL is Ext.SSL_SECURE_URL.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext-property-SSL_SECURE_URL

I think if needed you can change that setting before uploading and, maybe, restore after upload.

paulc
Sep 26, 2013, 2:28 PM
Thanks Daniil... that might work.

I am using the file upload control, but I the target is a different server.

Basically, the web server/database is hosted in a data centre in London and the uploaded files are stored on Amazon S3 in Dublin. So, the form is generated and rendered and posted to a different url. The IFRAME uses the london url nd so I get a security exception from Chrome because it's being manipulated from a response received from the dublin server.

Daniil
Sep 26, 2013, 2:36 PM
Interesting. Please notify it is going to work or not.