允许admin-ajax.php接收“application/json”而不是“x-www-form-urlencode”

时间:2015-02-09 作者:aendra

我在用AngularJS的$http 函数将我的有效负载发送到WordPressadmin-ajax.php 子系统,但后者似乎只接受x-www-form-urlencoded 数据,而不是application/json 由Angular提供。

我知道there are ways 使$http函数更像$.post(), 但这是荒谬的——既然已经是JSON,为什么还要将一堆JSON数据转换成一种形式呢?

为此目的—is there any way of instructing admin-ajax to consume type as application/JSON instead of x-www-form-urlencoded?

2 个回复
最合适的回答,由SO网友:gmazzap 整理而成

后者似乎只接受x-www-form-urlencoded

这不完全是真的。

WordPressadmin-ajax.php 从中执行操作$_REQUEST[\'action\']$_REQUEST 等于:

array_merge($_POST, $_GET);
但很多人没有意识到的是$_GET 在PHP中是not 数据是使用HTTP GET方法发送到页面的,事实上,您可以使用任何HTTP方法(POST、PUT、DELETE…)以及任何内容类型$_GET 将始终包含传递给url查询字符串的数据。

这意味着如果你向wp-admin/admin-ajax.php?action=awesome_action 无论您使用的HTTP方法和HTTP内容类型如何,都会始终达到“awesome\\u action”。

简而言之,如果您能够用url发送action参数,那么可以使用admin-ajax.php 要发送任何JSON数据和HTTP方法your 解决问题。

但是这很容易使用php://input 流动

示例

首先,我将编写一个函数,使用curl发送JSON内容类型的HTTP请求(因为我不想在这里编写角度代码):

/**
 * @param string $url  Url for for the request
 * @param string $data JSON-encoded data to send
 */
function mySendJson($url, $data)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); // PUT HTTP method
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        \'Content-Type: application/json\',           // JSON content type
        \'Content-Length: \' . strlen($data))
    );
    return curl_exec($ch);
}
很简单。

现在,出于测试目的,我将在前端页脚中放置一个函数,该函数使用上面的函数发送JSON内容类型的HTTP请求,并期望返回一些JSON:

add_action(\'wp_footer\', function() {

    $ajax_url = admin_url(\'admin-ajax.php?action=json-test\');

    // some dummy json data
    $data = array("name" => "Giuseppe", "country" => "Italy");
    $json = json_encode($data);

    // Using curl we simulate send HTTP request with json content type
    // in your case is Angular that perform the request
    $json_response = mySendJson($ajax_url, $json);

    echo \'<pre>\';
    print_r(json_decode($json_response, true));
    echo \'</pre>\';
});
现在,什么时候admin-ajax.php 它将查找附加到的任何回调\'wp_ajax_json-test\' 挂钩(或\'wp_ajax_nopriv_json-test\') 对于未登录的用户。

让我们为这些挂钩添加一个自定义函数:

add_action(\'wp_ajax_json-test\', \'myWpAjaxTest\');
add_action(\'wp_ajax_nopriv_json-test\', \'myWpAjaxTest\');
功能myWpAjaxTest() 将具有JSON内容类型的HTTP请求发送到时,WordPress将调用admin-ajax.php.

让我们写下来:

function myWpAjaxTest() {
    // Retrieve HTTP method
    $method = filter_input(INPUT_SERVER, \'REQUEST_METHOD\', FILTER_SANITIZE_STRING);
    // Retrieve JSON payload
    $data = json_decode(file_get_contents(\'php://input\'));

    // do something intersting with data,
    // maybe something different depending on HTTP method

    wp_send_json(array(  // send JSON back
      \'method\'        => $method,
      \'data_received\' => $data
    ));
}
感谢php://input (docs) 最后一个函数

解析发送到的JSON数据admin-ajax.php

  • 对其进行操作
  • 发回JSON响应(因为wp_send_json uses json content type)

    Array
    (
        [method] => PUT
        [data_received] => Array
            (
                [name] => Giuseppe
                [country] => Italy
            )
    
    )
    

  • SO网友:Mark Kaplun

    admin-ajax.php 设计用于处理jQuery,如果您不在JS站点上进行转换,则必须在服务器端进行转换才能正常工作。相反,您可以添加自己的可以处理json的“端点”。这种方法的最大问题是WP在“前端”URL上运行的查询。

    结束

    相关推荐

    使用JQuery/AJAX从MySQL动态填充层叠下拉菜单

    我想要实现的是以与MS Access相同的方式管理WordPress页面前端的表。所以,我想显示由外键关联的依赖级联下拉列表,然后单击一些按钮来执行插入/更新查询。老实说,我觉得很奇怪,没有什么东西(甚至没有高级插件)可以做这样的操作,因为它们真的很有用,几乎被所有企业使用。