You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress AJAX请求返回验证页面而非预期JSON响应问题

WordPress AJAX请求返回验证页面的问题

场景与代码

在WordPress中运行AJAX调用,后端与前端代码如下:

后端PHP代码

add_action('wp_ajax_my_plugin_check_r', 'my_plugin_check_r');

function my_plugin_check_r() {
    if(isset($_POST['token'])){
        $token = trim($_POST['token']);
        $response = ... do something
        echo json_encode($response);
        wp_die();
    }else{
        echo json_encode(false);
        wp_die();
    }
}

前端JS代码

var postData = [
    {name: 'action', value: 'my_plugin_check_r'},
    {name: 'token', value: v},
];

$.ajax({
    url: ajax_url,
    type: 'post',
    data: postData,
    dataType: 'json',   
}).done(function(r){
    var response = JSON.parse(r)
}).fail(function(jqXHR, textStatus, errorThrown) {
});

异常现象

请求返回的并非代码生成的JSON响应,而是一段包含“Please wait while your request is being verified...”的HTML验证页面,内容如下:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
<title>One moment, please...</title>
<style>
body {
    background: #F6F7F8;
    color: #303131;
    font-family: sans-serif;
    margin-top: 45vh;
    text-align: center;
}
</style>
</head>
<body>
<h1>Please wait while your request is being verified...</h1>
<form id="wsidchk-form" style="display:none;" action="/z0f76a1d14fd21a8fb5fd0d03e0fdc3d3cedae52f" method="get">
<input type="hidden" id="wsidchk" name="wsidchk"/>
</form>
<script>
(function(){
    var west=+((+!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![])+(+!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+![])+(+!+[]+!![]+!![]+!![]+!![]+!![]+[])+(+!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![])+(+!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+!+[]+!![]+!![])),
        east=+((+!+[]+!![])+(+!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+!+[]+!![]+!![])+(+!+[]+!![]+!![]+!![]+!![]+!![]+[])+(+!+[]+!![]+!![]+!![]+!![]+!![])+(+![]+[])+(+!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![])),
        x=function(){try{return !!window.addEventListener;}catch(e){return !!0;} },
        y=function(y,z){x() ? document.addEventListener("DOMContentLoaded",y,z) : document.attachEvent("onreadystatechange",y);};
    y(function(){
        document.getElementById('wsidchk').value = west + east;
        document.getElementById('wsidchk-form').submit();
    }, false);
})();
</script>
</body>
</html>

网络面板显示状态码为200 OK,响应头信息:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://www.....
Age: 0
Cache-Control: no-cache, must-revalidate, max-age=0, no-store, private
Content-Encoding: gzip
Content-Length: 657
Content-Type: text/html; charset=UTF-8
Date: Mon, 08 Jan 2024 18:40:59 GMT
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Pragma: no-cache
Referrer-Policy: strict-origin-when-cross-origin
Server: Apache
Vary: Accept-Encoding
Via: 1.1 webcache1 (Varnish/trunk)
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/8.1.27
X-Robots-Tag: noindex
X-Varnish: 1639091928

提问

该异常的原因是什么?该如何解决?


问题原因与解决方案

原因分析

从响应头的Via: 1.1 webcache1 (Varnish/trunk)和返回的验证页面来看,这是Varnish缓存或服务器层的人机验证机制触发了拦截。这类机制通常会针对非浏览器发起的请求、缺少必要Cookie/请求头的AJAX请求进行验证,防止自动化脚本或爬虫访问。

另外,前端代码存在冗余问题:dataType: 'json'已经告知jQuery自动解析JSON响应,但done回调里又调用JSON.parse(r),这会导致报错,但并非返回验证页面的直接原因。

解决方案

1. 确保AJAX请求携带必要验证信息

WordPress默认AJAX请求需要携带会话Cookie,同时要保证ajax_url是通过wp_localize_script传递的admin-ajax.php地址。修改前端请求,补充必要的请求头和Cookie配置:

var postData = {
    action: 'my_plugin_check_r',
    token: v
};

$.ajax({
    url: ajax_url,
    type: 'post',
    data: postData,
    dataType: 'json',
    xhrFields: {
        withCredentials: true
    },
    headers: {
        'X-Requested-With': 'XMLHttpRequest'
    }
}).done(function(r){
    // 无需再次解析,r已是处理好的JSON对象
    console.log(r);
}).fail(function(jqXHR, textStatus, errorThrown) {
    console.error(errorThrown);
});

2. 绕过Varnish对AJAX请求的验证

如果服务器使用Varnish,可在VCL配置中添加规则,跳过对admin-ajax.php的缓存验证:

sub vcl_recv {
    if (req.url ~ "^/wp-admin/admin-ajax.php$") {
        return (pass); // 直接透传至后端,不缓存
    }
}

3. 检查WordPress安全插件设置

Wordfence、iThemes Security等安全插件会对AJAX请求做额外验证,需将你的AJAX动作my_plugin_check_r加入插件的白名单,避免被拦截。

4. 修复前端JSON解析冗余问题

删除done回调中的JSON.parse(r),避免重复解析导致的语法错误。


内容的提问来源于stack exchange,提问作者Toniq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 16:57:02