0

I'm facing a bit of an odd problem here. I just launched: http://claudiu.phpfogapp.com/ To keep it short, when you minify your files or custom code or both, it returns a JSON string containing various data:

{
    "source" : MINIFIED_CSS,
    "location" : CSS_URL,
    ...
    "error_msg" : ERROR_MSG
}

Where the words typed in caps are actually the values. It works for a few lines of code, but breaks on large values of MINIFIED_CSS. It's weird that JavaScript doesn't issue any errors as well. I read the JSON with jQuery like this:

$.get('/minify/', {custom: $('.custom textarea').val(), files: JSON.stringify(request_string)}, function(data) {

                    console.log(data);
                    var response = eval(data);

When the MINIFIED_CSS is too large, I can't even see the console.log() call, but inspecting with Firebug you can see the source and can also see the JSON tab in Firebug for the request parsing the JSON nicely.

I have no idea what could be wrong. I'm sure that the JSON string doesn't break, I even created a small CSS file with the most awkward characters that could break the JSON: http://claudiuceia.info/css/small.css but minifying that runs smoothly. Did anyone face this problem before? Any ideas what could be wrong?

Hoping that having an actual link to the problem can help finding a solution quicker but if you need anything else please let me know, I don't know what else I could try. Also, note that this stopped working just now, but it worked when I launched a few hours ago? I tested in Chrome and Firefox and it worked, now it doesn't work in any of them.

UPDATE

I followed Scottie's suggestion (comment below) and ran the response through JSONlint.com The requests that I'm having problems with don't validate in JSONLint but running them through eval() doesn't issue an error and converts nicely: http://claudiuceia.info/demo/json/index.html

I'm expecting to see that, or at least an error or the console.log() call in the live app as well. The console.log() call should display even if data is null or undefined or whatever it might be.

Pictures with the requests working but not being read by JavaScript as well:

Firebug JSON tab for the request

Firebug response tab for the request

UPDATE 2

Looks like json_encode() didn't escape the CSS text properly for some reason. I had to use a solution found on this page: PHP's json_encode does not escape all JSON control characters

$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c"); 
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b"); 
$result = str_replace($escapers, $replacements, $value); return $result;
Community
  • 1
  • 1
Claudiu
  • 3,261
  • 1
  • 15
  • 27
  • Silly question, but have you run your resulting JSON through http://www.jsonlint.com to make sure it's valid? It sounds like you've troubleshooted (troubleshot?) for special characters and such, but there might be something else in there causing your problem. – Scott Jun 24 '11 at 09:11
  • I did, but I can't track the error since the string is minified. Still, in that case, eval() should issue an error or at least I should see the console.log() call, right? – Claudiu Jun 24 '11 at 09:14
  • 1
    can you post some CSS that causes the error ? The link you have has the returned JSON. If i take that minified CSS and re-run it causes the error, but if i replace the `\'` with just `'` it works fine.. could it be that you have `\'` in your original CSS ? – Gabriele Petrioli Jun 24 '11 at 10:25
  • I'll replace that, but shouldn't the console.log() call print something to the console anyhow? Or at least a javascript error on the eval() function? Anyhow, can you please edit your answer to include this as well if this is the problem so I can mark it as accepted? – Claudiu Jun 24 '11 at 10:32
  • Gaby, indeed, the "\" was the problem, but also another character I have in my test CSS file: ".clearfix:after { content: "\0020";" (the \0020). Will look into it and fix it, please let me know when you edit your answer to include this. – Claudiu Jun 24 '11 at 10:46

3 Answers3

2

If .custom textarea text is too long, you may exceed the maximum URI length error, resulting in HTTP 416 status code (you can see status code of the request in firebug console as well, usually it marks in red all request that are not with status 200 response. So you have to use $.post instead of $.get

Edit: based on the discussion below, the question is why callback function is not being called. Here is the answer :

The callback function is called only if the request succeeds. Since the response contains content-type application/json and browser can't parse json (the xmlhttp object contains statusText 'parseerror') the callback is never executed. If you add 'text' as last parameter to $.post() in order to parse the response as text, the callback will be executed and response will be logged

Maxim Krizhanovsky
  • 26,265
  • 5
  • 59
  • 89
  • Please see the comment to the similar answer and read again. Sending the data is not the problem, but reading the data. I did change to $.post though just because I had no limit on the textarea, but doesn't have anything to do with my problem. – Claudiu Jun 24 '11 at 09:20
  • Can you screenshot the firebug with the request, on the response tab. Maybe you are receiving 0 bytes response, meaning there is a problem at /minify/ script? Check error log for any memory exhausting or another fatal errors – Maxim Krizhanovsky Jun 24 '11 at 09:40
  • That's why I gave the link. If you read the question from end to end you will see that I already said the response is being displayed fine and also the JSON is interpreted correctly in Firebug. – Claudiu Jun 24 '11 at 09:43
  • Ok, I've tried with large CSS file, copied the response and tried to json_decode() it in PHP. The result is JSON_ERROR_SYNTAX. Maybe you have to provide the backend code? – Maxim Krizhanovsky Jun 24 '11 at 09:53
  • But I don't use PHP to decode the JSON! Dude, you're pushing me to down-vote you. This is about reading the response and parsing the response with JavaScript. What does the back-end code have to do with that? I'll copy the relevant bits and post that as well but really, it has absolutely nothing to do with it. A good example: http://claudiuceia.info/demo/json/index.html If you run that with PHP's json_decode() you'll probably get an error as well. With eval() it's being parsed as it should. – Claudiu Jun 24 '11 at 09:57
  • Obviously you are producing non-valid JSON code (as stated by you in the comment that you can't track the error since the string is minified). Since my response is not of any usefulness to you, I'm just stoping trying. And downvoting is your right :) – Maxim Krizhanovsky Jun 24 '11 at 09:59
  • See me edited comment. I need to know why I can't read the data, or parse it if it gets read. None of these have anything to do with the backend code, which generates the JSON. – Claudiu Jun 24 '11 at 10:03
  • The callback function is called only if the request succeeds. Since the response contains content-type application/json and browser can't parse json (the xmlhttp object contains statusText 'parseerror') the callback is never executed. If you add 'text' as last parameter to $.post() in order to parse the response as text, the callback will be executed and response will be logged. Can I help you with anything else? – Maxim Krizhanovsky Jun 24 '11 at 10:24
  • I don't know where you got this from, but it's false. – Claudiu Jun 24 '11 at 10:33
  • I get this from jQuery documentation, then tried to call your /minify/ with 'text' parameter and received a console.log() call, so give it a try :) – Maxim Krizhanovsky Jun 24 '11 at 10:37
  • Seriously, no, Gaby found the problem, it's in the comments below my question. Also, I have an unsuported character in the css file I'm testing with: ".clearfix:after { content: "\0020";" (the \0020). You can read JSON with $.get or $.post without any problems at all, FYI. Thanks for trying though. – Claudiu Jun 24 '11 at 10:45
  • Gaby found the reason your JSON is invalid, but not why console.log is not called. Anyway, I'm glad you've resolved your problem and I'm sorry I've frustrated you with my initial comments. Wish you all the best – Maxim Krizhanovsky Jun 24 '11 at 10:51
  • Darhazer, the console.log() gets/should get called when you read a JSON string with $.get or $.post. I don't know what you mean? – Claudiu Jun 24 '11 at 10:54
  • 2
    When you read a JSON response, but the JSON is not valid, the callback function is not called, which was part of your question. If you tell jQuery to read it as text instead, it would be called and probably you'll get JS error on the eval statement. If you wish, just try it (with mailformed json response). Anyway, this is just an answer to " Still, in that case, eval() should issue an error or at least I should see the console.log() call, right?" and similar comments and have nothing to do with the invalid JSON response at all. – Maxim Krizhanovsky Jun 24 '11 at 10:58
0

Maybe the problem is that you are using $.GET and when the CSS (or other value you are passin) is too big, it truncates it. The maximum length is at around 2000 characthers. Try to use $.POST that has no such limitations (well, it's limited by the value of your post_max_size in php ini.

Read here for more info: What is the maximum length of a URL in different browsers?

Community
  • 1
  • 1
Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192
  • The problem isn't with sending the request, but with reading the contents from the PHP file, read again. Thanks for the tip, I had no limit on the textarea and didn't think of that. The files are sent to the PHP script as URLs, not the contents themselves, so everything runs fine, the CSS is minified and the JSON is created. – Claudiu Jun 24 '11 at 09:19
0

problem 1
You are using .get() which has a limit on the number of bytes it can send over the URL..
Use '.post()' instead..

possible problem 2
You are using the console.log command, so if you do not have the console open, your code crashes there..


Update

Testing your examples i see that the CSS contains the \ character and that seems to choke the json parser which handles it as the escape char..

You need to escape that to \\ for the json parser to handle it correctly.

As you mention in your edited question, there is a series of chars that need to be properly encoded..

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • This is another duplicate answer. Using .get() is a problem when sending large quantities of data, not reading. I'm sending the file URLs not contents so I'm nowhere near the limit. I did changed to post though just in case. I put console.log() in there when the problem ocured to debug. Obviously I noticed that somehow the code isn't running because the console.log() call doesn't run and yes, with my console open. – Claudiu Jun 24 '11 at 09:23
  • @Claudiu.. don't get defensive .. i'm just trying to help and list the issues I encountered when testing your page.. – Gabriele Petrioli Jun 24 '11 at 10:22
  • I know and I appreciate that, but I was under the impression that you haven't fully read the question before posting your answer. – Claudiu Jun 24 '11 at 10:25