我使用我的JavaScript客户端(比如foo.js
)在服务器中调用我的php Ajax代码(比如bar.php
)。这在大多数情况下都非常有效,但偶尔我会返回 HTTP 403(禁止访问)而不是通常的 200(OK)。这是使用完全相同的代码、相同的参数等发生的。
为什么会这样?我该如何解决它?是否有可能由于我的bar.php
代码中的某些操作而发生?如何记录原因?
foo.js
客户端:
function postAjax(url, queryString, callback) {
var x = new XMLHttpRequest();
x.onreadystatechange = function() {
if (x.readyState === 4) { // 4=after HTTP response content finished loading
if (x.status === 200) callback(true, x.responseText);
else callback(false, x.status);
}
};
x.open('POST', url, true);
x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
x.setRequestHeader('Content-type','application/x-www-form-urlencoded');
x.send(queryString);
}
var params = 'aaa=xxx&bbb=yyy';
postAjax('bar.php', params, myCallback);
function myCallback(ajaxStatus, ajaxResponse) { /* do something */ }
bar.php
服务器:
<?php
header('Content-Type: text/plain');
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
if ($isAjax) {
/* Do something with $_POST['aaa'] and $_POST['bbb'] */
echo 'Success';
}
else {
echo 'Error';
}
?>
附加的新信息:
浏览器控制台(在本例中为火狐浏览器):
当一切正常时(大多数时候):
+ 发布 http://example.com/bar.php 200 OK ZZZms
当错误时(例如,在第 7 次之后,我最后一次尝试):
+ 发布 http://example.com/bar.php 403 禁止 X ZZZms
我在 ajaxResponse 中返回 403,它来自 x.status
展开Firefox控制台中的" +",我看到响应:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /bar.php
on this server.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>
查看 Apache Raw Accwss 日志(通过 cPanel),我看到所有人都有一个类似的 POST 行,在第 7 次测试中状态从 200 更改为 404:
<my IP> - - [17/Jan/2015:09:55:50 -0500] "POST /bar.php HTTP/1.1" 404 - "<my test url>" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
"您无权访问"???
为什么我有 6 次许可而不是第 7 次?
同时查看Apache错误日志(通过cPanel),我看到以下行:
[Sat Jan 17 09:55:50 2015] [error] [client <my IP>] File does not exist: /home/<my user>/public_html/403.shtml, referer: <my test url>
做了一些彻底的研究。它。。。mod_security!!
查看 http://www.opensourceforu.com/2011/08/securing-apache-part-10-mod_security/,搜索"SecFilterScanPOST"。我的"aaa"发布变量充当一些随机令牌,偶尔会有一个值被这种mod_security机制过滤。
此问题已在与主持人支持人员聊天后修复。最初我以为我可以通过适当地编辑一些 .htaccess 文件来自己解决它,但最终看来我需要他们的帮助。