帮助进行AJAX前端评论审核

时间:2014-01-03 作者:ScruffyDan

我正在为我管理的网站实现一个前端AJAX评论调节系统,但我很难让它正常工作。现在单击批准评论的链接会运行正确的php脚本,但会重新加载整个页面。所以它是可行的,但我希望在不重新加载整个页面的情况下使用ajax批准评论,但我缺乏javascript知识,这阻碍了我的工作。以下是代码(位于插件中):

add_filter( \'comment_text\', \'p3_comment_moderation_buttons\' );
function p3_comment_moderation_buttons ( ) {
    if ( is_author() || current_user_can( \'moderate_comment\' ) ) {
        // Adds moderation buttons under every comment
        $comment_id = get_comment_ID();
        $text = get_comment_text();
        $nonce = wp_create_nonce( \'p3_comment_moderation\' );

        $p3_approve_link = admin_url(\'admin-ajax.php?action=p3_comment_approve&comment_id=\'. $comment_id.\'&nonce=\'.$nonce);

        $p3_edit_links = \'<div class="p3-edit-links"><a class="p3-comment-moderation" href="\' . $p3_approve_link . \'" data-comment_id="\' . $comment_id . \'" data-nonce="\' . $nonce . \'">Approve</a></div>\';
        return $text . $p3_edit_links;
    }
    else{
        return get_comment_text();
    }
}


add_action("wp_ajax_p3_comment_approve", "p3_comment_approve");
function p3_comment_approve() {
    if ( ! wp_verify_nonce( $_REQUEST[\'nonce\'], \'p3_comment_moderation\' ) ) {
        exit("Go away!"); //If nonce check fails stop everything
    }
    $comment_id = $_REQUEST["comment_id"];
    $success = wp_set_comment_status( $comment_id, \'approve\' );
    $success = update_comment_meta( $comment_id, \'p3_comment_status\', \'\' );

    if ( $success = true ) {
        $result[\'type\'] = \'success\';
        $result[\'comment_id\'] = $_REQUEST["comment_id"];
    }
    else {
        $result[\'type\'] = \'error\';
        $result[\'comment_id\'] = $_REQUEST["comment_id"];
        echo "Something didn\'t work";
    }

    if(!empty($_SERVER[\'HTTP_X_REQUESTED_WITH\']) && strtolower($_SERVER[\'HTTP_X_REQUESTED_WITH\']) == \'xmlhttprequest\') {
        $result = json_encode($result);
        echo $result;
    }
    else {
        header("Location: ".$_SERVER["HTTP_REFERER"]);
    }

    die(); // this is required to return a proper result
}

add_action( \'init\', \'p3_comment_meta_script_enqueuer\' );
function p3_comment_meta_script_enqueuer() {
    wp_register_script( "p3_comment_meta", plugins_url().\'/p3wp-comments/js/p3_comment_meta.js\', array(\'jquery\') );
    wp_localize_script( "p3_comment_meta", \'p3cmetaAjax\', array( \'ajaxurl\' => admin_url( \'admin-ajax.php\' )));

    wp_enqueue_script( \'jquery\' );
    wp_enqueue_script( \'p3_comment_meta\' );
}
以及相应的javascript:

jQuery(document).ready( function() {

    jQuery(".p3-comment-moderation").click( function() {
        comment_id = jQuery(this).attr("data-comment_id")
        nonce = jQuery(this).attr("data-nonce")

        jQuery.ajax({
            type : "post",
            dataType : "json",
            url : p3cmetaAjax.ajaxurl,
            data : {action: "p3_comment_meta", comment_id : comment_id, nonce: nonce},
            success: function(response) {
                if(response.type == "success") {
                    alert("Success!")
                }
                else {
                    alert("Something went wrong.")
                }
            }
        })

    })

})
有人能发现问题吗?

顺便说一句,我已经修改了评论模板,以显示未批准的评论,以便可以在前端批准。我还计划将其扩展到使用自定义注释元,并扩展javascript,使其能够执行比显示恼人的警报更有用的操作

谢谢

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

在我看来,唯一的问题是您在链接中放置了完整的approve url,这样当您单击链接时,就会触发ajaxand 在链接中打开页面url。

更清楚的是,您的链接类似于:

<a class="p3-comment-moderation" href="admin-ajax.php?action=p3_comment_approve&comment_id=123&nonce=xxxxx" data-comment_id="123" data-nonce="xxxxx">Approve</a>
多亏了javascript,当您单击链接时,您会启动一个ajax请求,但没有任何东西阻止触发默认链接行为,因此admin-ajax.php 是浏览器所必需的header 语句,然后该页再次返回到当前页。

所以,事实上,情况就是这样:

ajax被触发admin-ajax.php 由中的url打开a 标记由于header("Location: ".$_SERVER["HTTP_REFERER"]) 代码中的语句我知道,即使用户禁用了javascript,将完整url放在链接中也是使其正常工作的正确方法,但启用javascript时,必须防止默认链接行为,这可以通过preventDefault() js函数。

因此,在javascript中替换

jQuery(".p3-comment-moderation").click( function() {
使用

jQuery(".p3-comment-moderation").click( function(e) {
    e.preventDefault();
After that everything should work as expected.

如果,就像我猜的那样,这是唯一的问题,那么这个问题是纯javascript问题,所以这里没有话题。然而,为了让我的答案更具WordPress相关性,我想添加一些提示(无论脚本是否有效,只有最佳实践和改进)。

提示1:转义属性和链接

在WordPress中,当您将html输出中的某些内容作为标记属性输出时,最佳做法是使用esc_attr, 一般使用全部esc_* 适用时的功能

$p3_edit_links = \'<a class="p3-comment-moderation" href="\' . $p3_approve_link . \'" data-comment_id="\' . $comment_id . \'" data-nonce="\' . $nonce . \'">Approve</a>\';
最好写下:

$p3_edit_links_f = \'<a class="p3-comment-moderation" href="%s" data-comment_id="%d" data-nonce="%s">\';
$p3_edit_links = sprintf($p3_edit_links_f, esc_url($p3_approve_link), esc_attr($comment_id), esc_attr($nonce) );
我知道您可以从WP核心函数获取URL和属性,但是一旦核心的几乎所有输出都可以过滤,就可以应用数据验证(尽管数据验证函数也可以过滤…)

提示2:使用核心常量检查ajax请求

if( ! empty($_SERVER[\'HTTP_X_REQUESTED_WITH\']) && strtolower($_SERVER[\'HTTP_X_REQUESTED_WITH\']) == \'xmlhttprequest\') {
检查当前请求是否来自ajax。在WordPress中正确使用admin-ajax.php (和您一样)您可以检查ajax请求以查找DOING_AJAX 常量,因此前一条条件语句变为:

if ( defined(\'DOING_AJAX\') && DOING_AJAX ) {
技巧3:使用核心函数输出json并退出脚本

$result = json_encode($result);
echo $result;
...
die();
可以使用核心在一行中写入wp_send_json 作用

wp_send_json( $result );
提示4:当您必须处理superglobals ($_REQUEST, $_GET, $_POST...) 为了避免出现通知,您应该始终检查您要查找的密钥是否已设置,以便

if ( ! wp_verify_nonce( $_REQUEST[\'nonce\'], \'p3_comment_moderation\' ) ) {
最好写下:

if ( ! isset($_REQUEST[\'nonce\']) || ! wp_verify_nonce( $_REQUEST[\'nonce\'], \'p3_comment_moderation\' ) ) {
但是,使用filter_var 而不是直接访问超全局

$nonce = filter_var( INPUT_GET, \'nonce\', FILTER_VALIDATE_STRING);
if ( empty($nonce) ) $nonce = filter_var( INPUT_POST, \'nonce\', FILTER_VALIDATE_STRING);
if ( ! wp_verify_nonce( $nonce, \'p3_comment_moderation\' ) ) {

结束

相关推荐

WP本地化脚本在自定义AJAX请求中不起作用

我正在尝试使用wp_localize_script() 将一些php值发送到脚本。以下是文件的一部分inc/show-event.php.if( $price ) { $pricefortwo = ceil( ( 2 * $price) - ( 0.2 * $price ) ); $savefortwo = ( 2 * $price) - $pricefortwo; $priceforthree = ceil( ( 3 * $price) -