PDA

View Full Version : [CLOSED] [4.0.7] filefield and json-answer with html-code in it doesn't work



ontho
28 Feb 2012, 3:43 AM
REQUIRED INFORMATION
Ext version tested:

Ext 4.0.7

Browser versions tested against:

FF 10.0.2 and Chrome 17.0

Steps to reproduce the problem:

Create a form
Add a filefield
Transfer as a result of submitting a text conainting html, like: ({"success":true,"data":{"description":"<p>Hello<\/p><p>world</p>"})

The result that was expected:

response.responseText should be ({"success":true,"data":{"description":"<p>Hello<\/p><p>world</p>"}

The result that occurs instead:

response.responseText is ({"success":true,"data":{"description":"<p>Hello&lt;\/p&gt;</p><p>world&lt;\/p&gt;"})</p>
See that the browser added an additional </p> to the response in the iframe?
This makes the following code throwing a "You're trying to decode an invalid JSON String"-exception.


HELPFUL INFORMATION

Possible fix:
Ext.data.Connection.onUploadComplete uses: response.responseText = doc.body.innerHTML; to get the response from the server when the form contains an upload-field. There, the html-code seem to be already corrupted (tried to be interpreted by the browser?!). In Chrome, you could use doc.body.innerText instead of innerHTML to get a non-corrupted version of the answer, but innerText doesn't seem to be available in FF.

Operating System:


Win7

evant
28 Feb 2012, 3:50 AM
From the docs:



The server response is parsed by the browser to create the document for the IFRAME. If the server is using JSON to send the return object, then the Content-Type header must be set to "text/html" in order to tell the browser to insert the text unchanged into the document body.

ontho
28 Feb 2012, 3:53 AM
Thanks a lot. I use:
header('content-type: text/html; charset="UTF-8"', true);
to make sure this is true. I tried several other content-types, just to make sure.

Please see that the problem ONLY occurs when sending HTML-Code inside the answer!

Please have a look as well to the error-message:
uncaught exception: You're trying to decode an invalid JSON String:
{"success":true,data{"description":"<p>Hello&lt;\/p&gt;</p><p>world&lt;\/p&gt;"}}</p>

Why is there an additional </p> at the end? This is from the browser misinterpreting the JSON answer and trying to make a "valid" html-structure out of it.

ontho
28 Feb 2012, 4:23 AM
Here is a small workaround. It only transmits non-html-code and therefor works:

Server-Reply:


<?php
...
$sResponse = JEncode($aAjaxResponse);
if (strpos($_SERVER["CONTENT_TYPE"], "application/x-www-form-urlencoded") === false)
{ $sResponse s = htmlspecialchars($sResponse, ENT_NOQUOTES);
}
print $sResponse ;
...?>


Javascript:


Ext.override(Ext.data.Connection,
{
onUploadComplete: function(frame, options) {
var me = this,

response = {
responseText: '',
responseXML: null
}, doc, firstChild;
try {
doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document;
if (doc) {
if (doc.body) {
if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) {
response.responseText = firstChild.value;
} else {
response.responseText = doc.body.innerHTML;
}
}

response.responseXML = doc.XMLDocument || doc;

// Fix: Decode the html we encoded on the server
response.responseText = Ext.htmlDecode(response.responseText);
}
} catch (e) {
}

me.fireEvent('requestcomplete', me, response, options);

Ext.callback(options.success, options.scope, [response, options]);
Ext.callback(options.callback, options.scope, [options, true, response]);

setTimeout(function(){
Ext.removeNode(frame);
}, 100);
}
});


Now it works.