简体   繁体   English

未捕获的语法错误:JSON 中的意外令牌 < position 中的 0 JSON.parse - Wordpress

[英]Uncaught SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse - Wordpress

I am new to AJAX and It seems like I might be missing a quite fundamental detail.我是 AJAX 的新手,看来我可能遗漏了一个非常基本的细节。 If I do this locally without using Wordpress, it works correctly.如果我在不使用 Wordpress 的情况下在本地执行此操作,它会正常工作。 I am sending you the link:我把链接发给你:

But if I create a function with Wordpress it comes out:但是,如果我用 Wordpress 创建一个 function,它就会出现:

Uncaught SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse未捕获的语法错误:JSON 中的意外令牌 < position 中的 0 JSON.parse

This is my code:这是我的代码:

add_action( 'wp_head', 'conta_visite');
function conta_visite(){
    
    $dir = get_stylesheet_directory() . "/users";
    if (!file_exists($dir)) {
    wp_mkdir_p( $dir );
        
}
if(isset($_POST['getCustomerCount']))
{

    $dbfile = get_stylesheet_directory() . "/visitors.db"; // path to data file
    $expire = 3; // average time in seconds to consider someone online before removing from the list
    if(!file_exists($dbfile)) {
        echo json_encode(['success'=> false,'error_message'=>"Error: Data file " . $dbfile . " NOT FOUND!"]);
        die();
        //die("Error: Data file " . $dbfile . " NOT FOUND!");
    }

    if(!is_writable($dbfile)) {
        echo json_encode(['success'=> false,'error_message'=>"Error: Data file " . $dbfile . " is NOT writable! Please CHMOD it to 666!"]);
        die();
        //die("Error: Data file " . $dbfile . " is NOT writable! Please CHMOD it to 666!");
    }

    $count = CountVisitors($dbfile, $expire);
    if(is_numeric($count)){
        $out = $count; // format the result to display 3 digits with leading 0's
        echo json_encode(['success'=>'true', 'customer_count'=>$out]);
    }
    else 
    {
        echo json_encode(['success'=> false, 'error_message'=>"count is not numeric"]);
    }
}
else{
    echo $dbfile;
    echo json_encode($_POST);
}


function CountVisitors() {
    global $dbfile, $expire;
    $cur_ip = getIP();
    $cur_time = time();
    $dbary_new = array();

  $dbary = json_decode(file_get_contents($dbfile),true);
    if(is_array($dbary)) {
      
      foreach($dbary as $user_ip => $user_time){
        if(($user_ip != $cur_ip) && (($user_time + $expire) > $cur_time)) {
                $dbary_new[$user_ip] = $user_time;
            }
      }
    }
  
    $dbary_new[$cur_ip] = $cur_time; // add record for current user

    $fp = fopen($dbfile, "w");
    fputs($fp, json_encode($dbary_new));
    fclose($fp);

    return count($dbary_new);
}

function getIP() {
    if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    elseif(isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    else
    {
        $ip = "0.0.0.0";
    }
    return $ip;
}

    
?>

<p id="customer_count">Customers Online: <span></span></p>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        function updateCustomerCount() {
  $.ajax({
    type: "POST",
    cache: false,
    data: {getCustomerCount: true},

        success: function(response) {

            var data = JSON.parse(response);
            //var data = response;
            console.log(response);
            if (data.success) {
                $("#customer_count span").text(data.customer_count);
            } else {
                console.log(data.error_message);
            }

        },
        error: function(response, request, status, error) {
            console.log(error);
        }
    });
setTimeout(updateCustomerCount, 2000);
} 
updateCustomerCount();
        
</script>

<?php
}

This is the Demo link in Wordpress: You can find the counter in the upper right corner of the header.这是Wordpress中的Demo链接:header右上角可以找到计数器。


Can you help me?你能帮助我吗? Because I'm going crazy and I can't figure out where I'm going wrong....因为我快疯了,我不知道我哪里出错了……

Ok so this should do what you're looking for.好的,这应该可以满足您的需求。 I've rewritten your code for better WordPress integration.我已经重写了您的代码以更好地集成 WordPress。

First, you'll need to create a new javascript file name visitor-counter.js and place it a js folder in your themes directory.首先,您需要创建一个新的 javascript 文件名visitor-counter.js并将其放置在您的主题目录中的一个js文件夹中。 This will be used for our jQuery and ajax request.这将用于我们的 jQuery 和 ajax 请求。

/js/visitor-counter.js

(function($) {

    window.VisitorCounter = window?.VisitorCounter || {

        /**
         * @type {object} Temp storage object
         */
        _temp: {},

        /**
         * Get a PHP variable.
         *
         * @param varName
         * @returns {*}
         */
        getVar(varName) {
            const vars = window?.VisitorCounterVars;
            return vars?.[varName];
        },

        /**
         * Make ajax request to server, store response in temp object.
         *
         * @returns {Promise<unknown>}
         */
        request() {
            return new Promise((accept, reject) => {
                const url = this.getVar('ajaxUrl');
                const action = this.getVar('ajaxAction');
                const post_id = this.getVar('post_id');

                if (url && action) {
                    $.ajax({
                        url: url,
                        data: {
                            action: action,
                            post_id: post_id
                        },
                        cache: false
                    }).then(response => {
                        this._temp.count = response.data;
                        accept(response);
                        console.log(response);
                    });
                } else {
                    reject('Visitor counter ajax url or action not available.');
                }
            });
        },

        /**
         * Get the count value.
         *
         * @returns {number}
         */
        getCount() {
            return parseInt(this._temp?.count || 0);
        },

        /**
         * Refresh data continuously.
         *
         * @param {callback} callback
         * @param {number} timeout
         */
        refresh(callback, timeout) {
            this._temp.lastRefreshed = Date.now();

            this.request().then(() => {
                const now = Date.now();

                callback.apply(this);

                const timeoutDiff = now - this._temp.lastRefreshed;

                // If request took longer than timeout, run next refresh instantly.
                if (timeout && timeoutDiff >= timeout) {
                    this.refresh(callback, timeout);
                }

                // Request was quicker than timeout, queue next refresh call.
                else {
                    setTimeout(() => {
                        this.refresh(callback, timeout);
                    }, timeout - timeoutDiff);
                }
            });
        }
    };

    // Initiate refresh loop
    VisitorCounter.refresh(function() {
        $('#customer_count span').text(VisitorCounter.getCount());
    }, 2000);

})(jQuery);

Next add the below to your themes functions.php file...接下来将以下内容添加到您的主题 functions.php 文件中...

/functions.php

class VisitorCounter {
        
    private static $instance;

    /**
     * @var string $file Relative path to the tracking file.
     */

    public $file = 'users/';

    /**
     * @var int $expires Automatically expire vistor after X amount of seconds.
     */
    
    public $expires = 3;

    /**
     * @return $this
     */
    public static function init() {
        if ( !static::$instance ) {
            static::$instance = new static( ...func_get_args() );
        }

        return static::$instance;
    }

    /**
     * Get the full database file path and create file if not exists.
     *
     * @return string|false
     */
    public function getPath() {

        $post_id = $_GET['post_id'];
        $path = get_stylesheet_directory() . '/' . ltrim( $this->file, '/' ) . 'product-view-id-' . $post_id . '.db';
        $exists = file_exists( $path );

        if ( !$exists ) {
            wp_mkdir_p( dirname( $path ) );
            $exists = touch( $path );
        }
        return $exists ? $path : true;
    }
    /**
     * Read the contents of the visitors database file as a JSON.
     *
     * @return array
     */
    public function getData() {
        if ( $path = $this->getPath() ) {
            if ( $contents = file_get_contents( $path ) ) {
                if ( $json = @json_decode( $contents, true ) ) {
                    return $this->cleanData( $json );
                }
            }
        }

        return [];
    }

    /**
     * Clean the visitor data by removing expired entries.
     *
     * @param array $input
     * @return array
     */
    private function cleanData( array $input ) {
        $now = time();

        foreach ( $input as $ip => $timestamp ) {
            if ( $timestamp + $this->expires < $now ) {
                unset( $input[ $ip ] );
            }
        }

        return $input;
    }

    /**
     * Add visitor count data.
     *
     * @param string $ip
     * @param int $timestamp
     * @return array
     */
    public function logUser() {
        
        // Get current data.
        $data = $this->getData();

        // Add new entry.
        if ( $ip = $this->getUserIp() ) {
            $data[ $ip ] = time();
        }

        // Clean data before saving.
        $data = $this->cleanData( $data );

        // Encode and save data.
        file_put_contents( $this->getPath(), wp_json_encode( $data ) );

        // Return data.
        return $data;
    }

    /**
     * Get the current users IP address.
     *
     * @return string|null
     */
    public function getUserIp() {

        // In order of preference, with the best ones for this purpose first.
        $address_headers = [
            'HTTP_CLIENT_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED',
            'HTTP_X_CLUSTER_CLIENT_IP',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED',
            'REMOTE_ADDR'
        ];

        $client_ip = null;

        foreach ( $address_headers as $header ) {
            if ( !empty( $_SERVER[ $header ] ) ) {
                /*
                 * HTTP_X_FORWARDED_FOR can contain a chain of comma-separated
                 * addresses. The first one is the original client. It can't be
                 * trusted for authenticity, but we don't need to for this purpose.
                 */
                $address_chain = explode( ',', $_SERVER[ $header ] );
                $client_ip = trim( $address_chain[ 0 ] );
                break;
            }
        }

        return $client_ip;
    }
}

/**
 * Helper function for visitor counter class.
 *
 * @return VisitorCounter
 */
function visitor_counter() {
    return VisitorCounter::init();
}


/**
 * Register an ajax request handler.
 */
add_action( 'wp_ajax_active_visitor', 'handle_visitor_activity' );
add_action( 'wp_ajax_nopriv_active_visitor', 'handle_visitor_activity' );
function handle_visitor_activity() {
    $controller = visitor_counter();
    $controller->logUser();
    wp_send_json_success( count( $controller->getData() ) );
}


/**
 * Load our javascript file on the frontend data.
 */
add_action( 'wp_enqueue_scripts', function() {
if ( is_product()) {
    // Load the counter javascript file after `jquery` in the footer.
    wp_enqueue_script( 'visitor-counter', get_stylesheet_directory_uri() . '/js/visitor-counter.js', [ 'jquery' ], '1.0.0', true );

    // Load php data that can be accessed in javascript.
    wp_localize_script( 'visitor-counter', 'VisitorCounterVars', [
        'ajaxUrl' => admin_url( 'admin-ajax.php' ),
        'ajaxAction' => 'active_visitor',
        'post_id'=> get_the_id()
    ] );
}
} );

Things to lookup...要查找的东西...

WordPress ajax handlers ( add_action( 'wp_ajax_' ) and add_action( 'wp_ajax_nopriv_' ) ) documentation can be found here: WordPress ajax 处理程序( add_action( 'wp_ajax_' )add_action( 'wp_ajax_nopriv_' ) )文档可以在这里找到:

WordPress JSON responses wp_send_json_error() and wp_send_json_success() : WordPress JSON 响应wp_send_json_error()wp_send_json_success()

Loading javascript on the frontend:在前端加载 javascript:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 未捕获到的SyntaxError:JSON中的意外令牌&lt;在JSON.parse位置0处( <anonymous> ) - Uncaught SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) JSON.parse 单个变量 - Uncaught SyntaxError: Unexpected token &lt; in JSON - JSON.parse single variable - Uncaught SyntaxError: Unexpected token < in JSON JSON.parse引发Uncaught SyntaxError:JSON中位置0处的意外令牌s - JSON.parse throwing Uncaught SyntaxError: Unexpected token s in JSON at position 0 Uncaught SyntaxError: Unexpected token &lt; in JSON at position 0 at JSON.parse (<anonymous> ) 在 XMLHttpRequest。<anonymous></anonymous></anonymous> - Uncaught SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.<anonymous> Uncaught SyntaxError: Unexpected token &lt; in JSON at position 0 : at JSON.parse (<anonymous> ) 在对象。<anonymous> - Uncaught SyntaxError: Unexpected token < in JSON at position 0 : at JSON.parse (<anonymous>) at Object.<anonymous> VM299:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse (<anonymous> ) - VM299:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse (<anonymous>) SyntaxError: JSON JSON JSON.parse 0 中的意外标记 - SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse SyntaxError:JSON中的意外令牌&lt;位于JSON.parse(位置0) <anonymous> )-AngularJS - SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) - AngularJS 未捕获的SyntaxError意外的数字JSON.parse - Uncaught SyntaxError Unexpected Number JSON.parse 未捕获到的SyntaxError:JSON中的意外令牌&lt;在JSON.parse的位置2 <anonymous> )在对象上。 <anonymous> (userhistory.js:23) - Uncaught SyntaxError: Unexpected token < in JSON at position 2 at JSON.parse (<anonymous>) at Object.<anonymous> (userhistory.js:23)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM