主頁 > 軟體工程 > 未捕獲的語法錯誤:JSON.parse中位置0處的JSON中的意外標記<-Wordpress

未捕獲的語法錯誤:JSON.parse中位置0處的JSON中的意外標記<-Wordpress

2022-06-02 00:59:51 軟體工程

我是 AJAX 新手,似乎我可能遺漏了一個非常基本的細節。如果我在不使用 Wordpress 的情況下在本地執行此操作,則它可以正常作業。我給你發鏈接:

但是如果我用 Wordpress 創建一個函式,它就會出現:

未捕獲的語法錯誤:JSON.parse 中位置 0 處的 JSON 中的意外標記 <

這是我的代碼:

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
}

這是 Wordpress 中的 Demo 鏈接:您可以在標題的右上角找到計數器。


你能幫助我嗎?因為我快瘋了,我不知道我哪里錯了......

uj5u.com熱心網友回復:

好的,所以這應該可以滿足您的要求。我已經重寫了您的代碼以獲得更好的 WordPress 集成。

首先,您需要創建一個新的 javascript 檔案名visitor-counter.js并將其放置js在主題目錄中的檔案夾中。這將用于我們的 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' );

                if ( url && action ) {
                    $.ajax( {
                        url: url,
                        data: {
                            action: action
                        },
                        cache: false
                    } ).then( response => {
                        this._temp.count = response.data;
                        accept( 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 );

接下來將以下內容添加到您的主題 functions.php 檔案中...

/functions.php

class VisitorCounter {

    private static $instance;

    /**
     * @var string $file Relative path to the tracking file.
     */
    public $file = '/users/visitors.db';

    /**
     * @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() {
        $path = get_stylesheet_directory() . '/' . ltrim( $this->file, '/' );

        $exists = file_exists( $path );

        if ( !$exists ) {
            wp_mkdir_p( dirname( $path ) );
            $exists = touch( $path );
        }

        return $exists ? $path : false;
    }

    /**
     * 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() {

    // Load the counter javascript file after `jquery` in the footer.
    wp_enqueue_script( 'visitor-counter', get_template_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'
    ] );

} );

要查找的東西...

WordPress ajax 處理程式(add_action( 'wp_ajax_' )add_action( 'wp_ajax_nopriv_' ))檔案可以在這里找到:

  • https://developer.wordpress.org/plugins/javascript/ajax/
  • https://developer.wordpress.org/reference/hooks/wp_ajax_action/
  • https://developer.wordpress.org/reference/hooks/wp_ajax_nopriv__requestaction/

WordPress JSON 回應wp_send_json_error()wp_send_json_success()

  • https://developer.wordpress.org/reference/functions/wp_send_json_error/
  • https://developer.wordpress.org/reference/functions/wp_send_json_success/

在前端加載 javascript:

  • https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/
  • https://developer.wordpress.org/reference/functions/wp_enqueue_script/
  • https://developer.wordpress.org/reference/functions/wp_localize_script/

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/484600.html

標籤:php jQuery json 阿贾克斯 WordPress

上一篇:PhpStorm:突出顯示Elementor主干模板

下一篇:在woocommerce上購買后,哪個是掛鉤操作的最佳方式?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more