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