Ajax-вызов PHP скрипт возвращает ошибку 404
Я дизайнер WordPress, я разработал контактную форму для одной из моих тем, которая была проверена с помощью jQuery.
Пожалуйста, проверьте код ниже, затем прочитайте примечания ниже.
$('.submitemail') .click(function() {
//VALIDATION CODE GOES HERE
if ( /*VALIDATED SUCCESSFULLY*/ ) {
$.ajax({
type: 'POST',
url: templatePath+'/lib/scripts/sendEmail.php',
data: 'visitorname=' + visitorname + '&visitoremail=' + visitoremail + '&visitormessage=' + visitormessage,
success: function(contactResults) {
//SUCCESS CODE
}
});
}
});
Примечания:
- sendEmail.php - это правильный script, который отправляет электронное письмо с использованием класса PHPmailer.
- variablePath variable имеет значение полного пути шаблона, которое выглядит следующим образом: http://somedomain.com/wp-content/themes/themename
- Код jQuery выше расположен в lib/scripts/jfunctions.js(тот же каталог php script)
- Весь процесс (ajax и php) работает отлично, как ожидалось, на многих серверах (тестируется на двух серверах мной и другими серверами пользователями моей темы).
Проблема:
На некоторых серверах обработчик успеха не запускается, а вызов ajax для sendEmail.php фактически успешно передается и обрабатывается php script и отправляется сообщение электронной почты.
Когда я проверяю с помощью firebug, чтобы узнать, почему обработчик успеха не запускается, firebug показывает "не найдена ошибка 404", он как ложный сигнал тревоги.
Возможные причины:
Я думаю, что некоторые серверы настроены на блокировку таких вызовов ajax.
Что может быть причиной этой странной проблемы? Как это исправить?
Спасибо заранее.
@nowk: код sendEmail.php:
<?php
// Code for loading WordPress environment goes here //
$themeName_optionTree = get_option('option_tree');
$name = trim($_POST['visitorname']);
$email = $_POST['visitoremail'];
$message = $_POST['visitormessage'];
$site_owners_email = $themeName_optionTree['owner_email'];
$site_owners_name = $themeName_optionTree['owner_name'];
$email_subject = $themeName_optionTree['email_subject'];
$success_message = '<p class="success-box">' . $themeName_optionTree['success_message'] . '</p>';
if (strlen($name) < 2) {
$error['name'] = 1;
}
if (!preg_match('/^[a-z0-9&\'\.\-_\+][email protected][a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $email)) {
$error['email'] = 1;
}
if (strlen($message) < 2) {
$error['message'] = 1;
}
if (!$error) {
require_once('PHPMailer_v5.1/class.phpmailer.php');
$mail = new PHPMailer(true);
try {
$mail->From = $email;
$mail->FromName = $name;
$mail->Subject = $email_subject;
$mail->AddAddress($site_owners_email, $site_owners_name);
$mail->Body = $message;
$mail->Send();
echo $success_message;
} catch (phpmailerException $e) {
echo '<p class="warning-box">' . $e->errorMessage() . '</p>';
} catch (Exception $e) {
echo '<p class="warning-box">' . $e->getMessage() . '</p>';
}
}
?>
Обратите внимание, что вышеприведенный код выполняется отлично, даже когда ajax возвращает 404, странно, да!
Ответы
Ответ 1
Так как сервер отправляет 404 (бог знает, в чем причина), есть два способа исправить/обойти это:
- Игнорировать код ответа HTTP и изменить
success
на complete
в jQuery ajax-вызове, чтобы обработчик выполнялся, когда запрос выполняется независимо от ответа сервера. Вы знаете ответ сервера (он всегда работает). HTML-код должен быть доступен в обработчике jQuery complete
.
- Перезапишите 404, что-то отправляет на сервер (возможно, что-то Wordpress), выполнив (перед печатью любого выхода):
header('HTTP/1.1 200 OK')
. Поскольку выполняется script, это перезапишет сумасшедший 404, а jQuery получит 200 и выполнит обработчик success
.
Вы можете попробовать оба =) Я уверен, что первый будет работать (но это не так чисто). Я также уверен, что второй будет работать, но я не знаю Wordpress достаточно хорошо, чтобы сделать promises =)
Ответ 2
Я предполагаю, что Wordpress уже имеет встроенный механизм AJAX и не позволяет вам реализовать его самостоятельно. На этой странице объясняется, как добавить AJAX к плагинам:
http://codex.wordpress.org/AJAX_in_Plugins
Вот фрагмент со страницы:
Ajax на стороне администрирования
Так как Ajax уже встроен в основные окна администрирования WordPress, добавление функциональности Ajax на стороне администратора для вашего плагина довольно просто, и в этом разделе описывается, как это сделать.
Вот краткий пример. Все это будет в одном файле.
Сначала добавьте javascript, который вызовет запрос AJAX:
<?php
add_action('admin_print_scripts', 'my_action_javascript');
function my_action_javascript() {
?>
<script type="text/javascript" >
jQuery(document).ready(function($) {
var data = {
action: 'my_action',
whatever: 1234
};
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
$.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
});
});
</script>
<?php
}
Затем создайте функцию PHP, которая будет обрабатывать этот запрос:
<?php
add_action('wp_ajax_my_action', 'my_action_callback');
function my_action_callback() {
global $wpdb; // this is how you get access to the database
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
echo $whatever;
die(); // this is required to return a proper result
}
Что это! Вам нужно будет добавить несколько деталей, таких как проверка ошибок и проверка того, что запрос пришел из нужного места (с помощью check_ajax_referer()), но, надеюсь, приведенного выше примера будет достаточно, чтобы вы начали свой собственный плагин Ajax на стороне администрирования,
ПРИМЕЧАНИЕ. Начиная с версии 2.8, глобальную переменную javascript ajaxurl можно использовать в том случае, если вы хотите отделить свой код javascript от php файлов в только файлы javascript. Это верно только для административной стороны.
Ответ 3
Как показано здесь https://cooltrainer.org/fixing-false-404-headers-on-external-pages-including-wp-blog-header-php/, это решение протестировано и работает хорошо:
require_once("path/to/wp-config.php");
$wp->init();
$wp->parse_request();
$wp->query_posts();
$wp->register_globals();
$wp->send_headers();
Ответ 4
Не вникая в проблему, вы можете проверить, что запрос ajax действительно идет туда, где вы думаете, что он собирается. Здесь может быть несколько вещей, например, сервер настроен для перенаправления любых запросов на/wp-content/где-то еще.
Захватите некоторую информацию заголовка с помощью firebug и, возможно, заголовков livehttp.