WordPress中使用AJAX的問題我們碰到的有不少了,今天php粉絲網小編來為各位介紹一些關于WordPress中使用AJAX的幾個問題總結,希望例子對各位有用。
使用AJAX的錯誤方法:
我看過很多的使用AJAX的插件,有些使用了正確的方法有些的實現方法則不對,這些不正確的插件使用的方法通常就是,使用一個PHP文件來響應ajax請求,另外的一個php文件來寫了些javascript的代碼.
下面是一個常見但是錯誤的例子:
require_once("../../../../wp-config.php");
// or require_once("../../../../wp-load.php");
這個用法之所以錯誤,是因為用戶有可能會使用其他的文件路徑,這樣上面的相對文件的讀取方法就有問題了。更進一步,如果你在插件中使用了面向對象的開發方法,你就不能夠直接訪問需要的類屬性和方法了。
上面的PHP代碼中,我們還需要另外一個PHP文件來輸出javascript文件。這樣一來,這個PHP文件又要加載wp-config.php或者wp-load.php,這還可能需要讀取數據庫的數據等。所以我們相當于把整個Wordpress框架又加載了一遍。
抱歉到現在都沒有給你展示正確的使用AJAX的方法,但是為了避免錯誤,我們需要把不利說說清楚,這樣才能自然而然的引入下面五點
1. 使用wp_localize_script()來聲明全局的javascript變量
盡管wp_localize_script()通常用于聲明國際化的代碼,它也可以有另外的用法。你可以使用它來聲明javascript的變量,甚至可以帶命名空間!下面是它的語法:
wp_localize_script($handle, $namespace, $variable_array);
然后是你怎么用它來聲明一個AJAX的全局對象(這個例子中我使用了admin-ajax.php,會在第二部分中講到):
- // 嵌入必要的js文件
- wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js', array( 'jquery' ) );
- // 什么響應請求的url (wp-admin/admin-ajax.php)
- wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); //Vevb.com
使用這種方法,你不需要使用PHP來輸出Javascript代碼,那可真是各種不爽,如果你看一下生成的HTML代碼,你也許會發現:
XHTML
- <script type="text/javascript" src="http://example.com/wordpress/wp-content/plugins/myajax/js/ajax.js"></script><script type="text/javascript">// <![CDATA[
- var MyAjax = { ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php" };
- // ]]></script>
現在,在你的ajax.js中,你就可以使用MyAjax.ajaxurl變量了,不需要wp-load.php。參考第二條學習關于收發請求的知識。
2.使用admin-ajax.php來響應AJAX請求
AJAX請求應該指向wp-admin/admin-ajax.php,好吧,我知道”admin”這個詞有點容易誤導人,不過即使是前臺的ajax請求,也應該定位到admin-ajax.php.
admin-ajax需要一個參數“action”,admin-ajax需要這個參數來處理請求,它通常觸發一個hook,根據是否登錄有所不同.
PHP:
- // 這個鉤子在沒有登錄時觸發
- do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
- // 如果登錄的話
- do_action( 'wp_ajax_' . $_POST['action'] );
JavasScript代碼的話有點象這樣:
JavaScript
- jQuery.post(
- MyAjax.ajaxurl,
- {
- // 這里需要傳一個參數,意味著觸發
- // wp_ajax_nopriv_myajax-submit 或 wp_ajax_myajax-submit
- action : 'myajax-submit',
- // 也可以跟一些其他的參數
- postID : MyAjax.postID
- },
- function( response ) {
- alert( response );
- }
- );
現在我們在插件或者主題里面寫一個實際的代碼來響應:
PHP
- // 這里假設登不登錄都可以發送請求
- add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit' );
- add_action( 'wp_ajax_myajax-submit', 'myajax_submit' );
- function myajax_submit() {
- // 獲取參數
- $postID = $_POST['postID'];
- // 生成響應
- $response = json_encode( array( 'success' => true ) );
- // 輸出響應
- header( "Content-Type: application/json" );
- echo $response;
- // IMPORTANT: 別忘了退出
- exit;
- }
3.使用nonces并且檢查權限
我想我不需要再重申檢查用戶請求權限的事情了。雖然開發者總是會有意無意忽略它,然后結果會很悲劇。沒有了適當的權限檢查,一個不懷好意的訪問者可以輕松毀了你煞費苦心打造的網站。這里我們要介紹兩種安全層。
Nonces
Nonces是Numbers that are generated and used once的縮寫(它是一個在加密通信只能使用一次的數字,通常翻譯為隨機數,但我覺得隨機數不太能夠完全表達它的含義,所以我下面還是用這個單詞,譯注)。Nonces保證了action由特定位置的授權用戶發起的。這里有Jon Sykes的有趣分析,這讓事情變得容易理解一些。
當你進入了一家熟食店,你會拿到一張票,當輪到你票上的號碼時,你拿著票交給服務員,服務員把票收下并作廢,然后為你提供服務。然后他們會接著為大屏幕上顯示號碼的顧客提供服務。
如果有不講文明的孩子進入店里試圖插隊,他們是不會得逞的,因為他們沒有票。
即使他們得到了其他顧客使用過的票,那也是不行的,因為票已經使用而且號碼也已經過去了。
我們再把這個場景擴展一下,當客戶得到一張票的時候,我們還給這個客戶在他的票上簽名。這樣一來,當服務員給顧客服務的時候,他不僅看票的號碼,也會讓顧客再次簽名,以和票上的簽名進行比較確定這張票是不是真的屬于這個顧客。
在擴展一下,我們限定只有顧客進入大門的時候發給他票然后在上面簽名,這會進一步防止有人趴在窗口試圖偽造顧客的簽名。因為他沒有進入大門,甚至連票也得不到一張。所以他根本沒有辦法插隊來買走那最后一根臘腸。
Mark Jaquith 和 Vladimir Prelovac 同樣對Nonces有精彩論述,讀一讀他們的文章,因為你肯定會在各種各樣WP開發中使用到這些東西的(不僅僅是AJAX相關)。
不過,這里也應該說明一下,Nonces只用作對數據內容有修改的情況下,如果只是讀取一些不敏感的信息,比如獲得評論的條數,或者一篇文章的內容,那么Nonces是不必要的。不過如果你是對一篇文章進行新增/編輯/刪除,那么確保你會使用Nonces。
好了,理論說的夠多的了,我們來看看如何使用它吧。
首先,你需要產生一個nonce,然后使用wp_localize_script()來包含這個變量
PHP
- // 調用相關的js文件
- wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js', array( 'jquery' ) );
- wp_localize_script( 'my-ajax-request', 'MyAjax', array(
- // 處理 wp-admin/admin-ajax.php 請求的URL
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
- // 使用一個唯一ID "myajax-post-comment-nonce" 產生nonce
- // 你可以在隨后的ajax請求中檢查他
- 'postCommentNonce' => wp_create_nonce( 'myajax-post-comment-nonce' ),
- )
- );
現在你可以在JS中使用全局變量MyAjax.postCommentNonce了,你可以在隨后的AJAX請求中發送這個值。
JavaScript:
- jQuery.post(
- MyAjax.ajaxurl,
- {
- action : 'myajax-submit',
- postID : MyAjax.postID,
- // 發送這個nonce值
- postCommentNonce : MyAjax.postCommentNonce
- },
- function( response ) {
- alert( response );
- }
- );
這基本和上一個例子差不多,除了我加了個nonce值發送給服務器。
這里有個事情要注意一下,如果你需要發送多次ajax請求,那么你必須在一次ajax請求中生成一個新的nonce值返回,然后用腳本更新這個值,在下一次ajax請求中再使用。否則這個nonce會在多次ajax請求中使用,就會出問題啦。
檢查權限:
很多腳本忽視了完整的權限檢查,記住使用current_user_can()來確定當前的用戶是被授權的,這里有一個終極版本的代碼來回應請求:
PHP:
- // 如果登錄和非登錄用戶都可以發送ajax請求,那么加下面兩種actions,
- // 否則只要設定需要授權的版本就好了
- add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit' );
- add_action( 'wp_ajax_myajax-submit', 'myajax_submit' );
- function myajax_submit() {
- $nonce = $_POST['postCommentNonce'];
- // 檢查提交的nonce是否和我們上次產生的一致
- if ( ! wp_verify_nonce( $nonce, 'myajax-post-comment-nonce' ) )
- die ( 'Busted!')
- // 如果當前用戶沒有足夠權限,忽視它
- if ( current_user_can( 'edit_posts' ) ) {
- // 獲得提交的參數
- $postID = $_POST['postID'];
- // 生成回應
- $response = json_encode( array( 'success' => true ) );
- // 輸出
- header( "Content-Type: application/json" );
- echo $response;
- }
- // 重要:別忘了"exit"
- exit;
- }
4.使用內置的jQuery表單插件來提交表單
大家都知道使用ajax來提交表單避免頁面的刷新,但不是不是所有人都知道wordpress提供了一個jquery的插件來處理表單的相關動作,要想使用這個插件,想下面一樣先包含它:
XHTML
<script src="https://gist.github.com/3827608.js"> </script>
譯注:這個JS莫名其妙,它這里說的應該是ajaxForm插件,請參看下面的鏈接.
然后提交表單就很輕松了:
JavaScript
- jQuery('#myForm1').ajaxForm({
- data: {
- // 除了表單元素意外的額外數據
- },
- dataType: 'json',
- beforeSubmit: function(formData, jqForm, options) {
- // 在發送數據前可以進行的額外處理
- },
- success : function(responseText, statusText, xhr, $form) {
- // 請求正確處理后的動作
- }
- });
這個插件還有很多參數,請自己查閱吧。
5.警惕jQuery自帶的JSON解析功能
原文撰寫時間較早,Wordpress版本為2.9.2,jQuery版本為1.3.2,這個版本的jQuery有時候會完全依靠eval來解析JSON數據,因而會有安全性問題,后續版本已有改進,我們現在接觸的版本應該都是安全的,因而這一點不在翻譯,否則反而混淆視聽了,譯注.
總結:
ajax是一把雙刃劍,它使得用戶體驗平滑而且迅捷,但是也帶來了復雜度的提升和安全檢查的繁雜,正確的使用它,安全的使用它,文章涵蓋了5個重要的使用ajax的注意點,遵守他們,確保您的代碼安全而且高效.
新聞熱點
疑難解答
圖片精選