There are a lot of people on this site reporting problems with an ajax error message box when attempting to add fields, modify settings etc when editing a view. Most solutions given involve turning off ajax/javascript editing in /admin/build/views/tools but this is an unsatifactory solution. I have solved this problem for me but this involves changes to drupal core files. The basic reason is that drupal_to_js does not produce valid json. The ajax callback then fails and the message box is shown. Read on...
Program flow:
I have a field in a view. I click it to modify it, and a jquery mod catches the click and the code in views/js/ajax.js runs. The ajax code at line 247 in ajax.js changes the URL from xxx/nojs/xxx to xxx/ajax/xxx, adds the "throbber" and some other CSS stuff, and runs an ajax call to xxx/ajax/xxx.
The code in views/includes/admin.inc is then called. This generates the HTML to modify the views page. This is then passed to views_ajax_render in views/includes/ajax.inc to render into json and send to the browser. This in turn is done by drupal_json() which itself sets the header and runs drupal_to_js in /includes/common.inc. Still with me?
The problem is that drupal_to_js does not produce valid json. The JSON specification is detailed at http://www.json.org/. There is a json validator at http://www.jsonlint.com/ which fails the json returned by drupal_to_js. The two main problems are as follows:
- The first is that drupal_to_js "use(s) HTML-safe strings, i.e. with <, > and & escaped." (common.inc line 2434). This means that < is replaced by \x3c, > by \x3e and & by \x26. However these strings (\xnn) are invalid json. The only valid hex code (see json.org) is \unnnn. So < should be replaced with \u003c, > by \u003e and & by \u0026. If common.inc is modified in this way (line 2445, 2446), the json is valid and the ajax call works without error
- The second problem is with apostrophies. For example, the text "User's Picture" or "Target of the link, such as _blank, _parent or an iframe's name." Json does not delimit apostrophies, but the json returned to the browser is in this format: "Target of the link, such as _blank, _parent or an iframe\'s name." - note the apostrophy in "iframe\'s". From json.org, the only legal delimited characters are \" \\ \/ \b \f \n \r \t \u four-hex-digits --- so not \' -- again such json fails the validator.
In summary, to fix all these problems, the following changes need to be made:
- fix drupal_to_js() to return valid json (or create a new function) where hex strings are \unnnn not \xnn
- fix drupal_to_js() or similar to remove the slashes added by addslashes, basically "undelimit" \' to '
I have modified drupal_to_js() in common.inc as follows and the errors go away completely
common.inc line 2444-2447
case 'string':
return '"'. str_replace(array("\r", "\n", "<", ">", "&"),
array('\r', '\n', '\u003c', '\u003e', '\u0026'),
str_replace("\'","'", addslashes($var))) .'"';
Clearly this is just a short-term fix but it does prove my point. I think that I will copy the code from drupal_json and drupal_to_js into view's ajax.inc, make the mods as above then run my own _views_drupal_json and _views_drupal_to_js within views.
Please email if this is not clear...
Comments
Comment #1
quicksketchEarl pointed this one out to me and I wanted to add what I could find on this issue.
- First, the encoding problems are already fixed in Drupal 7, see drupal_json_encode(). Which just adds further validity to the fact that we're currently doing something wrong.
- Pressflow suffers from this same problem, which may be the cause for this issue in the FileField Sources queue #696778: Problems with Pressflow install.
- I'm not sure anyone knows about the apostrophe problem, great find.
All in all, this is excellent sleuthing and very appreciated. I'd do anything to reduce the number of problems people have with AJAX uploading in FileField. We should find a permanent solution and move to get this fixed in core.
Comment #3
piersg CreditAttribution: piersg commentedLooking around, I've found a few other Issues dealing with this. One is #479368: D7: Create RFC compliant HTML safe JSON, although that topic's authors' solution looks a little over-engineered. I suppose that as this is a core issue it may be good to push ahead with trying to get their patch into core asap. It's been in the test queue for six weeks waiting to be checked. In the meantime, I'm pleased to have my ajax functionality back within the Views UI!
Comment #4
mobcdi CreditAttribution: mobcdi commentedIs it safe to make the changes to common.inc or is there a tested patch available for this?
I'm running d6.14 and Views 6.x-2.7
Comment #5
andyxmas CreditAttribution: andyxmas commentedworked a treat for me. thanks!
Comment #6
CinemaSaville CreditAttribution: CinemaSaville commentedYour code did not fix my problem, however Views 6.x-3 Alpha did. However there were other problems in there so I had to go back to Views 2, the weird thing is when I went back the problem was still gone. Man, what a mystery these things are. Just glad it's gone.
Comment #7
David StraussWhile a release isn't out yet, I have committed the fix to the JSON encoder in Pressflow.
Comment #8
sunchaser CreditAttribution: sunchaser commentedsolution sounded good , but didnt work for me either
6.x-2.10
Comment #9
jimshreds CreditAttribution: jimshreds commentedchange to common.inc not working here 6.x-2.10
Comment #10
nicanorflavier CreditAttribution: nicanorflavier commentedDidn't work for me either.
Comment #11
spudette77 CreditAttribution: spudette77 commentedUnfortunately did nothing for me either. Does anyone have any new ideas?
Comment #12
WAKeaney CreditAttribution: WAKeaney commentedhttp://drupal.org/node/849008#comment-3234982
I found that disabling SSL alleviated this problem. seutje on IRC pointed out that the async call is probably being made over http, which is considered crossdomain by javascript. Setting my base_url to specify https:// for the whole site did the trick perfectly, without modifying one line of code.
$base_url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on') ? 'https://' : 'http://') . 'mysite.com';
Comment #13
SleekSlimby CreditAttribution: SleekSlimby commentedDisabling "jquery-1.4.2.min.js" worked for me and people have confirmed that the latest jquery is not compatible with Views: http://drupal.org/node/768612
I rolled back to "jquery-1.4.1.min.js" and it worked for a while. It is working again now but I will have to confirm that the problem does not come back.
Comment #14
norm1710 CreditAttribution: norm1710 commentedCan confirm that #13 worked for me but the other solutions didn't
Comment #15
kurt-s CreditAttribution: kurt-s commentedPerfect, The solution provided by the author of the article worked for me. I would point out however that the fix is on line's 2498 through 2501 in my editor.
Comment #16
shunting CreditAttribution: shunting commentedThe change to common.inc did not work for me.
However, the change to views/includes/admin.inc, line 1559 did work:
http://mmbee888.wordpress.com/2009/11/06/drupal-views-module-ajax-error/
PHP 5.3.2, json 1.2.1, views-6.x-2.6, drupal-6.14.
Comment #17
HydroZ CreditAttribution: HydroZ commentedThanks for the fix, Pirsg!
This solved 3 issues, that are very often discussed:
- "Add another item", when trying to upload a file via cck-field
- FUpload, multi-file upload, showed me the progress bar but kept hanging with the message "Images in que are processed",
- and the above mentioned one: "An error occured" when using the Views UI.
From my site i can definitly determine, that the jQuery-Version is not reltaed to this issues. Tried with jQuery 1.2.2 (Drupal standard), 1.4.1,1.4.2,1.4.4.
Comment #18
blitux CreditAttribution: blitux commentedWorks for me. Drupal 6.20, jquery 1.4.3
Comment #19
walidvb CreditAttribution: walidvb commentedI made the change to common.inc as mentionned above, and the error disappeared. However, when I try to save a change i made(add a field/change view name/etc..) i get a page with
(full error in attachment)
so i'm guessing JSON now accepts the characters, but they're not the right ones to be used...
I also tried this: http://mmbee888.wordpress.com/2009/11/06/drupal-views-module-ajax-error/ , but this doesn't help either...
Views used to work, but not anymore.. anybody can help me on this?
thanks a lot.
Comment #20
walidvb CreditAttribution: walidvb commentedreally sorry, forgot the attachment :/
Comment #21
T1ckL35 CreditAttribution: T1ckL35 commentedFor reference when I got this problem:
I got the error (or a variation of it) when I manually upgraded from jquery 1.2.6 to 1.3.2. I backed up the files in the jquery_update/replace folder and then copied in the 1.3.2 versions. When I did this the error started and stopped me working with views.
I found that in the jquery_update admin settings it was set to use the 'packed' version. I had added a manually packed js version and the official js minified version but the packed one was dodgy/corrupt and was breaking views that relies on it. I did a switch to the minified one and the problem disappeared
Comment #22
adam_b CreditAttribution: adam_b commentedsubscribing - I got this when I copied an online site into a local WAMP environment.
Comment #23
claar CreditAttribution: claar commentedsub'ing -- same problem
Comment #24
decostar CreditAttribution: decostar commentedWorked for me when I turned off Javascript for Views in Tools.
Comment #25
shunting CreditAttribution: shunting commentedI encountered a similar error from apache's mod_security. Perhaps the server thought that "view" and "record" were part of a SQL injection? (mod_security's pattern recognition in cPanel seems to be just awful....)
Comment #26
mwalker_drupal CreditAttribution: mwalker_drupal commentedusing Drupal 6.20 and getting the css dump mentioned above when adding or modifying views settings. Noticed this issue after upgrading JQuery to the latest.
Fixed it by disabling javascript in Views UI.
Thanks decostar for the tip.
Comment #27
erald CreditAttribution: erald commentedDrupal 6.22 and views 6x.2.12 the common.inc change worked for me.
Comment #28
eric constantinides CreditAttribution: eric constantinides commentedAhhh, thank you so much!!! Fixed it for me in Drupal 6.22. It's line 2500 in that version btw. Thanks again.!
Comment #29
el_reverend CreditAttribution: el_reverend commentedNot sure if that has something to do with it, but once I log out and back in the error no longer appears. What, if anything could that have to do with the login?
In my case the error reports
Not sure if I wan to change the common.inc file since this is yet another piece to keep track of when the next update comes around. How safe would this be?
Comment #30
donquixote CreditAttribution: donquixote commentedThe correct D6 issue is
#1086098: D6 JSON is total garbage - Create RFC 4627 compliant HTML safe JSON
Comment #31
rajeesh CreditAttribution: rajeesh commentedDear piersg , your changes in common.inc fixed my issues. But now I need to create a patch for applying those changes. Can you please guide me to create patch for the changes.
Thanks in advance.
Comment #32
klonos@rajeesh: Hey Rajeesh, Creating a patch with Git is what you're after ;)
Comment #33
rajeesh CreditAttribution: rajeesh commentedI created a patch for it. But it was not working. I don't know what's wrong with it. Here is my patch.
Comment #34
klonosFrom taking a look in other .patch files, it seems that the patch should have a header in the form of:
Are you sure you used the right command parameters?
Comment #35
MustangGB CreditAttribution: MustangGB commented