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 前,下列有幾個觀念需要有。
- 前端頁面:
- 需要建立一個「自定義參數」
- wp_create_nonce方法是用來產生「驗證碼」,並且要指定給 參數 data 中的 ‘nonce’
- Ajax 中的 URL ,必需是指向 ajaxurl,否則 Ajax 的請求會失敗
- 後端伺服器:
接下來進入程式撰寫 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, );
這樣會產生操作畫面如下:
- 最後 $.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 ) ) { ... }
你必須 登入 才能發表評論。