PDA

View Full Version : Issue with Form submit method and JSON parsing when uploading a file to server



jeetmarwah
2 Feb 2012, 3:20 PM
I am working on a File Upload functionality where you get a popup , select a file and then click submit. The file should be uploaded and it returns a JSON string with different values.

The file on the server gets uploaded and I am also returning a JSON string from the server, but it gets appended with the <pre> tag somehow and throws an 'invalid JSON string' exception.

I am using extjs4.0.7 and it happens on FF10, Chrome 16.0.912.77 m.

Server is returning the following json string:


{'success':true,'msg':'File uploaded successfully.','postid':'qvQsBe33QjjSEJSlkoVWabzAlO3FggUi','fileurl':'<img src=/post/download?fileid=8a9482ed353fbc3b0135403d9dec0028 alt=fghfghfg height=42 width=42 />'}


I get the following error in Chrome


Uncaught Ext.Error: You're trying to decode an invalid JSON String: <pre style="word-wrap: break-word; white-space: pre-wrap;">{'success':true,'msg':'File uploaded successfully.','postid':'LpJFok8yaQdlcRd15j0UBxWaKaY8yZHD','fileurl':'aaaa'}</pre>
Ext.Error.Ext.extend.statics.raiseext-debug.js:8460
(anonymous function)ext-debug.js:8702
Ext.define.handleResponse Submit.js:250
Ext.define.processResponse Action.js:236
Ext.define.onSuccess Submit.js:215
Ext.apply.callback ext-debug.js:8911
Ext.define.onUploadCompleteConnection.js:432
(anonymous function)ext-debug.js:2401


I get the following error in FF


uncaught exception: You're trying to decode an invalid JSON String: <pre>{'success':true,'msg':'File uploaded successfully.','postid':'LpJFok8yaQdlcRd15j0UBxWaKaY8yZHD','fileurl':'aaaa'}</pre>


My File upload code snnipet is as follows: (url and method='POST' is set at the form creation level)


uploadFile: function() {
var formToSubmit = this.getFileUploadForm().getForm();
var values = formToSubmit.getValues();
console.log('This should upload the file to the server now');

formToSubmit.submit({
clientValidation: true,
waitMsg: 'Uploading your file...',
params: {
postid: Ext.getCmp('postsysidid').getValue()
},
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);

//update the post
var textarea = Ext.getCmp('postcontentsid');
var newValue = textarea.getValue() + ' ' + action.result.fileurl;
textarea.setValue(newValue);

//set the postid
var postsysididHidden = Ext.getCmp('postsysidid');
postsysididHidden.setValue(action.result.postid);

//close the window
var windowOwner = form.owner.ownerCt;
windowOwner.close();
},
failure: function(form, action) {

switch (action.failureType) {
case Ext.form.action.Action.CLIENT_INVALID:
Ext.Msg.alert('Failure', 'Form fields may not be submitted with invalid values');
break;
case Ext.form.action.Action.CONNECT_FAILURE:
Ext.Msg.alert('Failure', 'Ajax communication failed');
break;
case Ext.form.action.Action.SERVER_INVALID:
Ext.Msg.alert('Failure', action.result.msg);
}


var windowOwner = form.owner.ownerCt;
windowOwner.close();
}


});


},



Please advise.

Thanks,
Jeet

jeetmarwah
2 Feb 2012, 5:19 PM
Some more updates:

I tried setting the content type of my response to 'application/json' , 'text/html', etc but did not work.

To make this working, I have to change a line of code in Extjs source which is not a good practice and is a work around.

Changed in : src/data/Connection.js file
method : onUploadComplete
from :


response.responseText = doc.body.innerHTML;//appends <pre> tag for a json string

to:


response.responseText = doc.body.textContent || doc.body.innerText;



Will the Extjs team be making this change/fix in the coming releases? Is there a workaround for now?

Please advise.

Thanks,
Jeet

planadecu
19 Jul 2012, 6:29 AM
Hello,

I'm having the exact same problem. Changing the response type didn't work, I wonder whether is a hosted mode problem or it works on production with real html.

In my case the bug is in the GWT class com.google.gwt.dom.client.Element.FormPanelImpl


public native String getContents(Element iframe) /*-{
try {
// Make sure the iframe's window & document are loaded.
if (!iframe.contentWindow || !iframe.contentWindow.document)
return null;


// Get the body's entire inner HTML.
return iframe.contentWindow.document.body.innerHTML;
} catch (e) {
return null;
}
}-*/;


Any update?

jeetmarwah
19 Jul 2012, 11:25 AM
I think you are working on GXT/GWT. Please refer to this link for that.

http://www.sencha.com/forum/showthread.php?89931-file-upload-example

For extjs, I have an update. We don't have to change the extjs file anymore. On the server side, if you are using Spring 3.x, make sure to use the server side as follows.



@RequestMapping(value = "/post/attach", method = { RequestMethod.POST })
@ResponseBody
public void attachFileToPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html"); //NOTE


StringBuffer result = new StringBuffer();
result.append("<html><head></head><body>");
try
{

//server side operation


result.append("{");
result.append("'success':true").append(",");
result.append("'msg':'File uploaded successfully.'").append(",");
result.append("'postid':'").append(postid).append("',");
result.append("'fileurl':'").append(htmlelement).append("'");
result.append("}");


}
catch (Exception e)
{
Log.log.error("error uploading file to a Post: file is " + displayName, e);


result.append("{");
result.append("'success':false").append(",");
result.append("'msg':'File uploaded failed.'").append(",");
result.append("'postid':'").append(postid).append("',");
result.append("'fileurl':''");
result.append("}");
}


System.out.println(result.toString());
result.append("</body></html>");
response.getWriter().print(result.toString());
// For a file upload we need to write directly to the response because
// returning a string messes up the browser when dealing with the form
// submission
}



Hope this helps.

Thanks,
Jeet