2020 年 6 月 3 日

IT Skills 波林

Polin WEI – 資訊工作者的技術手札

WordPress 撰寫 Ajax 功能範例

1 min read
小人國

WordPress 撰寫 Ajax 功能範例

AJAX 在維基百科提到,Ajax 即「Asynchronous JavaScript and XML」(非同步的JavaScript與XML技術),指的是一套綜合了多項技術的瀏覽器端網頁開發技術。傳統的Web應用允許用戶端填寫表單(form),當送出表單時就向網頁伺服器傳送一個請求。伺服器接收並處理傳來的表單,然後送回一個新的網頁,但這個做法浪費了許多頻寬,因為在前後兩個頁面中的大部分HTML碼往往是相同的。由於每次應用的溝通都需要向伺服器傳送請求,應用的回應時間依賴於伺服器的回應時間。這導致了使用者介面的回應比本機應用慢得多。

與此不同,AJAX應用可以僅向伺服器傳送並取回必須的資料,並在客戶端採用JavaScript處理來自伺服器的回應。因為在伺服器和瀏覽器之間交換的資料大量減少,伺服器回應更快了。同時,很多的處理工作可以在發出請求的客戶端機器上完成,因此Web伺服器的負荷也減少了。使用 Ajax 有另外一個好處,就是使用者在前端的作業畫面,不需要跳轉頁面,就可以完成向後端伺服器的請求。

在 WordPress 要完成 Ajax 的功能,必需要依它的規則來作業,不然它會失敗,這是因為它是為了避免被駭客從其它網站發出要求(request)來取得網站內資料或是執行函數。在  WordPress 使用 Ajax 功能是使用 JQuery ,所以對 JQuery 有一定的認識是必要的,在開發 Ajax 前,下列有幾個觀念需要有。

  • 前端頁面:
  1. 需要建立一個「自定義參數」
  2. wp_create_nonce方法是用來產生「驗證碼」,並且要指定給 參數 data 中的 ‘nonce’
  3. Ajax 中的 URL ,必需是指向 ajaxurl,否則 Ajax 的請求會失敗
  • 後端伺服器:
  1. wp_ajax_nopriv 與 wp_ajax  的 hook
  2. wp_verify_nonce 方法是用來驗證前端傳來的「驗證碼:nonce」+「自定義參數」

 

接下來進入程式撰寫 Ajax 。首先,定義一個「自定義參數:MY_AJAX_EXAMPLE_ACTION_NONCE」,並在檔案 ajax-example.php 中實作

define( 'MY_AJAX_EXAMPLE_ACTION_NONCE', 'my-ajax-example-action-' );
function wpwx_admin_ajax_example(){  
  include("ajax-example.php");
}

 

在檔案 ajax-example.php 中產生兩個 Button : “Ajax Primary” & “Ajax Secundary” 來作範例

<?php
  add_action( 'admin_ajax_notices', 'my_ajax_example_action_button' );

  function my_ajax_example_action_button() {
    $id   = 54321;
    $data = array(
        'data-nonce' => wp_create_nonce( MY_AJAX_EXAMPLE_ACTION_NONCE . $id ),
        'data-id'    => $id,
    );
    echo get_submit_button( "Ajax Primary", 'primary large', 'my-ajax-example-action-button-1', FALSE, $data );

    $id   += 12345;
    $data = array(
        'data-nonce' => wp_create_nonce( MY_AJAX_EXAMPLE_ACTION_NONCE . $id ),
        'data-id'    => $id,
    );
    echo get_submit_button( "Ajax Secundary", 'secondary', 'my-ajax-example-action-button-2', FALSE, $data );
  }
  my_ajax_example_action_button();

 

  • 程式碼中 wp_create_nonce( MY_AJAX_EXAMPLE_ACTION_NONCE . $id ) 就是用來產生 「驗證碼」
$data = array(
        'data-nonce' => wp_create_nonce( MY_AJAX_EXAMPLE_ACTION_NONCE . $id ),
        'data-id'    => $id,
    );

這樣會產生操作畫面如下:

wp-ajax-example-button

 

  • 最後 $.post 的 url 要使用 ajaxurl,利用 admin_footer 的 Hook ,將下列的 javascript 加到操作頁面的最後端
<?php

  add_action( 'admin_footer', 'my_ajax_example_action_javascript' ); // Write our JS below here

  function my_ajax_example_action_javascript() {
      ?>
      <script type="text/javascript">
          jQuery(document).ready(function ($) {
              $('#my-ajax-example-action-button-1,#my-ajax-example-action-button-2').click(function () {
                  var $button = $(this);
  
                  var data = {
                      'action': 'my_ajax_example_action',
                      'id': $button.data('id'),
                      'nonce': $button.data('nonce')
                  };
                  // Give user cue not to click again
                  $button.addClass('disabled');
                  // Invalidate the nonce
                  $button.data('nonce', 'invalid');
  
                  $.post(ajaxurl, data, function (response) {
                      alert('Got this from the server: ' + response);
  
                  });
              });
          });
      </script>
      <?php
  }

 

在這裡是否有一個疑問? ajaxurl 到底是什麼呢? 這是因為 WordPress 在 HTML 頁面一開始就定義好了 ajaxurl  參數,所有其它的 Url 都將會被阻擋

<script type="text/javascript">
addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
var ajaxurl = '/wp-admin/admin-ajax.php',
  pagenow = '%e5%be%ae%e4%bf%a1%e8%a8%8a%e6%81%af%e6%95%b4%e5%90%88_page_weixin-wechat-message',
  typenow = '',
  adminpage = '-e5-be-ae-e4-bf-a1-e8-a8-8a-e6-81-af-e6-95-b4-e5-90-88_page_weixin-wechat-message',
  thousandsSeparator = ',',
  decimalPoint = '.',
  isRtl = 0;
</script>

到這裡,前端的操作 HTML頁面就完成了。

 

 

  • wp_ajax_nopriv 與 wp_ajax  的 hook

wp_ajax_nopriv 是一個組合事件,以此開頭的 AJAX 事件為「不需登入即可使用」的做法,少了 nopriv 關鍵字就是必須要登入才可以使用的方法,例如:wp_ajax_my_ajax_example_action, 整個後端程式如下:

/**
 * Ajax Example
 */
add_action( 'wp_ajax_my_ajax_example_action', 'my_ajax_example_action' );

function my_ajax_example_action() {
    global $wpdb; // this is how you get access to the database

    $id    = $_POST['id'];
    $nonce = $_POST['nonce'];
    if ( wp_verify_nonce( $nonce, MY_AJAX_EXAMPLE_ACTION_NONCE . $id ) ) {
        $response = intval( $id );
        $response += 10;
        echo $response;
    } else {
        echo - 1;
    }
    wp_die(); // this is required to terminate immediately and return a proper response
}

 

 

  • 而 wp_verify_nonce 方法是用來驗證 CSRF Token ,避免跨站隨意請求。
$id    = $_POST['id'];
$nonce = $_POST['nonce'];
if ( wp_verify_nonce( $nonce, MY_AJAX_EXAMPLE_ACTION_NONCE . $id ) ) {
...
}

 

Copyright © All rights reserved. | Newsphere by AF themes.