2

I'm running Drupal 7.34 with quite a few modules (relevant because unfortunately I did not notice when the problem first started and it would take ages to look through them all one by one) and I have some quite strange behaviour. Whenever I try to fill in an autocomplete text field, manually check for updates or do anything else that involves AJAX really, I get an error message with the HTTP Response Code 200 and the response text is actually the HTML of the user profile page. One exception to this is in a custom module I wrote which uses callbacks, and strangely when the callback is outputted any persistent messages (i.e operating in maintenance mode) are also displayed in the same place. I have tried disabling and deleting this module but it did not change anything.

Also, I suspect it could be related that my messages log is filled with warnings saying:

Warning: Cannot modify header information - headers already sent by (output started at /home/site.com/public_html/includes/common.inc:2725) in drupal_goto() (line 697 of /home/site.com/public_html/includes/common.inc).

Does anybody have any idea what could be causing this?

9
  • 1
    Each ajax request returns the HTML for the user profil page? Don't you have a redirection set up from a hook_init or something? You should try saving a backtrace to see where the drupal_goto is called from. Commented Dec 28, 2014 at 13:29
  • @thedotwriter Not that I know of but I will have a quick look. How would I go about saving the backtrace?
    – Andy
    Commented Dec 28, 2014 at 14:14
  • 1
    You could add dpm(debug_backtrace()); at the line 697 of common.inc, launch the AJAX request and refresh the page. Maybe the devel message won't be rendered when the user profil page is generated. If you can't get the trace to be displayed with dpm(), you'll need to save the array returned by debug_backtrace() somewhere in a log file with watchdog() or error_log(). Commented Dec 28, 2014 at 14:24
  • @thedotwriter Ok, so this is the start of the array that is returned... Any idea what my next step should be? 0 => array ( 'file' => '/home/site.com/public_html/modules/php/php.module(80) : eval()\'d code', 'line' => 18, 'function' => 'drupal_goto', 'args' => array ( 0 => 'user', ), ), 1 => array ( 'file' => '/home/site.com/public_html/modules/php/php.module', 'line' => 80, 'function' => 'eval', ), 2 => array ( 'file' => '/home/site.com/public_html/modules/filter/filter.module', 'line' => 799, 'function' => 'php_eval', 'args' => array ( 0 => '<?php
    – Andy
    Commented Dec 28, 2014 at 14:39
  • Well, I was hoping to find a call to a custom function but it's not always that simple. Nothing like that on the backtrace? Commented Dec 28, 2014 at 14:46

1 Answer 1

0

Thanks to some brilliant and generous help from @thedotwriter, I believe I have found the cause of this problem and a solution.

In turns out that the root of the redirection to the user profile page, which meant that the AJAX response text was the code of that page, was some PHP code similar to the following, in one of my nodes:

if(!user_is_logged_in()){
   drupal_goto("user");
}

At first, this seemed odd because the node was in no way related to AJAX. To complicate the issue further, if the line was removed and then re-added once the node had been updated, AJAX worked again... for a few hours.

Looking in the log, I noticed that just before the error returned Cron had run. This made sense - sort of - because then I found that when I ran Cron manually it never completed but ended up on the user page, which can be explained by the fact that Cron would have evaluated the above code due to the fact that it runs as an anonymous user.

Here my answer falls down a bit because I'm not quite sure how this all affects AJAX. I'm assuming that it's due to caching and/or the fact that part of Cron indexes the site so therefore because Cron was being redirected the index was corrupt/incomplete. I don't have any solid evidence, but it can be backed up by the fact that before the site would only ever get up to being 82% indexed, but without that code it is now 100% indexed. If anyone would like to offer there thoughts on this answer however, please feel free to do as I really would like to confirm 'the missing piece of this puzzle'.

There are a few ways to avoid this issue. One would be to check to see if the script that is accessing the node is cron so that you know not to do any redirects (see here). However, the method I chose was to move this 'functionality' into a rule. I do so for many reasons, but most importantly because it is not recommended to use PHP codes in nodes at all and I think that this incident illustrates why.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.