thinkphp ajax 非同步 局部 刷新

来源:http://www.cnblogs.com/cquptzzq/archive/2017/09/11/7503957.html
-Advertisement-
Play Games

摘要:ThinkPHP是一個小型網站很常用的低端框架,但是不專業的文檔和編碼導致使用者很容易只知其表不知其里。這裡僅就官方文檔中未曾提及的在thinkphp中使用jquery實現ajax非同步交互略作總結。 環境:ThinkPHP3.2.3,jQuery 閱讀目錄: 正文: 在一般的網站中,都需要用到 ...


摘要:ThinkPHP是一個小型網站很常用的低端框架,但是不專業的文檔和編碼導致使用者很容易只知其表不知其里。這裡僅就官方文檔中未曾提及的在thinkphp中使用jquery實現ajax非同步交互略作總結。

環境:ThinkPHP3.2.3jQuery

閱讀目錄:

正文:

在一般的網站中,都需要用到jquery或者其他框架(比如angular)來處理前後端數據交互。在thinkphp在後臺也內置了一些函數用於數據交互(比如ajaxReturn())。本文的目的是打通jquery ajaxthinkphp的前後端數據交互過程。

前言:

一、thinkphp關於ajax的介紹

1.1 ajaxReturn

\Think\Controller類提供了ajaxReturn方法用於AJAX調用後返回數據給客戶端(視圖、模板、js等)。並且支持JSONJSONPXMLEVAL四種方式給客戶端接受數據(預設JSON)。(鏈接:http://document.thinkphp.cn/manual_3_2.html#ajax_return

配置方式:convention.php中定義了預設編碼類型為DEFAULT_AJAX_RETURN =>  'JSON',

分析:ajaxReturn()調用了json_encode()將數值轉換成json數據存儲格式,常用的數值是數組。

註意:The value being encoded can be any type except a resource(資源文件).All string data must be UTF-8 encoded.(鏈接:http://php.net/manual/en/function.json-encode.php

舉例:

$data['status']  = 1;

$data['content'] = 'content';

$this->ajaxReturn($data);

1.2 請求類型:

系統內置了一些常量用於判斷請求類型,比如:

常量 說明

IS_GET 判斷是否是GET方式提交

IS_POST 判斷是否是POST方式提交

IS_PUT 判斷是否是PUT方式提交

IS_DELETE 判斷是否是DELETE方式提交

IS_AJAX 判斷是否是AJAX提交

REQUEST_METHOD 當前提交類型

目的:一方面可以針對請求類型作出不同的邏輯處理,另外一方面可以過濾不安全的請求。 (鏈接:http://document.thinkphp.cn/manual_3_2.html#request_method

使用方法:

class UserController extends Controller{

     public function update(){

         if (IS_POST){

             $User = M('User');

             $User->create();

             $User->save();

             $this->success('保存完成');

         }else{

             $this->error('非法請求');

         }

     }

}

1.3 跳轉和重定向:

功能比較雞肋,在ajax非同步交互局部刷新中,不需要有文字提示的跳轉。(鏈接:http://document.thinkphp.cn/manual_3_2.html#page_jump_redirect

 

二、jQuery Ajax的介紹:

2.1 官網關於jQuery.ajax()的介紹

jQuery.ajax() 方法用於執行 AJAX(非同步 HTTP)請求。(鏈接:http://www.jquery123.com/jQuery.ajax/

語法:$.ajax({name:value, name:value, ... }),該參數規定 AJAX 請求的一個或多個名稱/值對。

常見參數:

type (預設: 'GET')

類型: String

請求方式 ("POST" "GET"), 預設為 "GET"。註意:其它 HTTP 請求方法,如 PUT DELETE 也可以使用,但僅部分瀏覽器支持。

url (預設: 當前頁面地址)

類型: String

發送請求的地址。

async (預設: true)1.8版本已棄用)

類型: Boolean

預設設置下,所有請求均為非同步請求(也就是說這是預設設置為 true )。如果需要發送同步請求,請將此選項設置為 false

data

類型: Object, String

發送到伺服器的數據。將自動轉換為請求字元串格式。GET 請求中將附加在 URL 後面。查看 processData 選項說明,以禁止此自動轉換。對象必須為"{:}"格式。如果這個參數是一個數組,jQuery會按照traditional 參數的值, 將自動轉化為一個同名的多值查詢字元串(查看下麵的說明)。註:如 {foo:["bar1", "bar2"]} 轉換為 '&foo=bar1&foo=bar2'

dataType (預設: Intelligent Guess (xml, json, script, or html))

類型: String

預期伺服器返回的數據類型。如果不指定,jQuery 將自動根據 HTTP MIME 信息來智能判斷,比如XML MIME類型就被識別為XML。在1.4中,JSON就會生成一個JavaScript對象,而script則會執行這個腳本。隨後伺服器端返回的數據會根據這個值解析後,傳遞給回調函數。舉例:

"json": 把響應的結果當作 JSON 執行,並返回一個JavaScript對象。在 jQuery 1.4 中,JSON 格式的數據以嚴格的方式解析,如果格式有錯誤,jQuery都會被拒絕並拋出一個解析錯誤的異常。(見json.org的更多信息,正確的JSON格式。)

error

類型: Function( jqXHR jqXHR, String textStatus, String errorThrown )

請求失敗時調用此函數。有以下三個參數:jqXHR (jQuery 1.4.x前為XMLHttpRequest) 對象、描述發生錯誤類型的一個字元串 和 捕獲的異常對象。如果發生了錯誤,錯誤信息(第二個參數)除了得到null之外,還可能是"timeout", "error", "abort" ,和 "parsererror"。 當一個HTTP錯誤發生時,errorThrown 接收HTTP狀態的文本部分,比如: "Not Found"(沒有找到) 或者 "Internal Server Error."(伺服器內部錯誤)。 從jQuery 1.5開始, error設置可以接受函數組成的數組。每個函數將被依次調用。 註意:此處理程式在跨域腳本和JSONP形式的請求時不被調用。這是一個 Ajax Event

success

類型: Function( Object data, String textStatus, jqXHR jqXHR )

請求成功後的回調函數。這個函數傳遞3個參數:從伺服器返回的數據,並根據dataType參數進行處理後的數據,一個描述狀態的字元串;還有 jqXHR(在jQuery 1.4.x前為XMLHttpRequest) 對象 。在jQuery 1.5, 成功設置可以接受一個函數數組。每個函數將被依次調用。這是一個 Ajax Event

其他jQuery-ajax-settings,詳見:http://www.jquery123.com/#jQuery-ajax-settings

 

舉例:

js中把id作為數據發送到伺服器, 保存一些數據到伺服器上, 一旦請求完成就通知用戶。  如果請求失敗,則提醒用戶。

var menuId = $("ul.nav").first().attr("id");

var request = $.ajax({

  url: "script.php",

  type: "POST",

  data: {id : menuId},

  dataType: "html"

});

request.done(function(msg) {

  $("#log").html( msg );

});

request.fail(function(jqXHR, textStatus) {

  alert( "Request failed: " + textStatus );

});

註意:此處也可以在ajax()中使用successerror參數判斷請求結果成功還是失敗,並執行下一步操作。

 

2.2 jsjson

2.2.1 json是什麼:

JSONJavaScript 對象表示法(JavaScript Object Notation)。是獨立於語言之外的存儲和交換文本信息的語法。

2.2.2 jsonajax的關係?

在上面關於jquery.ajax的介紹中提到了,json可以作為一個ajax函數的dataType,這樣數據就會通過json語法傳輸了。(鏈接:http://www.cnblogs.com/haitao-fan/p/3908973.html

jqueryajax函數中,只能傳入3種類型的數據:(鏈接:http://www.cnblogs.com/haitao-fan/p/3908973.html

>1.json字元串:"uname=alice&mobileIpt=110&birthday=1983-05-12"

>2.json對象:{uanme:'vic',mobileIpt:'110',birthday:'2013-11-11'}

>3.json數組:

[

    {"name":"uname","value":"alice"},

    {"name":"mobileIpt","value":"110"},   

    {"name":"birthday","value":"2012-11-11"}

]

2.2.3 json的編解碼和數據轉換:

2.2.2中提到的json對象是更方便與js數組、js字元串或php數組、php字元串進行數據轉化的json類型。下麵以json對象為例講解一下json對象與jsphp的數據類型轉化。

json對象轉化成數組:

<script type="text/javascript">

        var jsonStr = '[{"id":"01","open":false,"pId":"0","name":"A部門"},{"id":"01","open":false,"pId":"0","name":"A部門"},{"id":"011","open":false,"pId":"01","name":"A部門"},{"id":"03","open":false,"pId":"0","name":"A部門"},{"id":"04","open":false,"pId":"0","name":"A部門"}, {"id":"05","open":false,"pId":"0","name":"A部門"}, {"id":"06","open":false,"pId":"0","name":"A部門"}]';

      //  var jsonObj = $.parseJSON(jsonStr);

      var jsonObj =  JSON.parse(jsonStr)

        console.log(jsonObj)

     var jsonStr1 = JSON.stringify(jsonObj)

     console.log(jsonStr1+"jsonStr1")

     var jsonArr = [];

     for(var i =0 ;i < jsonObj.length;i++){

            jsonArr[i] = jsonObj[i];

     }

     console.log(typeof(jsonArr))

    </script>

想要將表單數據提交到後臺,需要先從表單獲取數據/數據集:

serializeserializeArray的區別是serialize()獲取到序列化的表單值字元串,serializeArray()以數組形式輸出序列化表單值。舉例:

var serialize_string=$('#form').serialize();

得到:a=1&b=2&c=3&d=4&e=5

var serialize_string_array=$('#form').serializeArray();

得到:

[

  {name: 'firstname', value: 'Hello'},

  {name: 'lastname', value: 'World'},

  {name: 'alias'}, // 值為空

]

相對來說,serializeArray()和最終想要得到的json數組更加相似。只不過需要將包含多個name-value形式json對象的json數組改寫成'first_name':'Hello'形式的json對象。

下麵有兩種轉換方法:http://blog.jdk5.com/zh/convert-form-data-to-javascript-object-with-jquery/

這裡使用第二種方法舉例,可以起名為change_serialize_to_json()

var data = {};

$("form").serializeArray().map(function(x){

if (data[x.name] !== undefined) {

        if (!data[x.name].push) {

            data[x.name] = [data[x.name]];

        }

        data[x.name].push(x.value || '');

    } else {

        data[x.name] = x.value || '';

    }

});

輸出:{"input1":"","textarea":"234","select":"1"}

 

完整流程:

var serialize=$('#form').serialize()結果(得到一個字元串,用serializeArray()更好,其中中文都會轉換成utf8):

serial_number=SN2&result=%E9%9D%9E%E6%B3%95

var serialize_array=$('#form').serializeArray()結果(結果是json對象數組):

Array [ Object, Object ]

var data=change_serialize_to_json(serialize_array)的結果是(以第二種轉換方法為例,結果是json對象):

Object {serial_number: "SN2", result: "非法" }

var json_data=JSON.stringify(data)(結果是json字元串):

{"serial_number":"SN2","result":"非法"}

 

js端將表單數據轉化為json形式的其他函數:

json字元串轉換為json對象:

eval("(" + status_process+ ")")

json字元串轉化成json對象:

// jquery的方法

var jsonObj = $.parseJSON(jsonStr)

//js 的方法

var jsonObj =  JSON.parse(jsonStr)

json對象轉化成json字元串:

//js方法

var jsonStr1 = JSON.stringify(jsonObj)

JSON.parse()用於從一個字元串中解析出json對象。JSON.stringify()相反,用於從一個對象解析出字元串。

(鏈接:http://blog.csdn.net/wangxiaohu__/article/details/7254598

 

str_replace() 函數用於替換掉字元串中的特定字元,比如替換掉數據轉換後多餘的空格、'/nbsp'

 

註意:serializeserializeArray()函數在處理checkbox時存在無法獲取未勾選項的bug,需要自己編寫函數改寫原函數,舉例:

(鏈接:http://www.cnblogs.com/tangge/p/6554891.html

//value賦值為off是因為正常的serializeArray()獲取到的勾選的checkbox值為on

$.fn.mySerializeArray = function () {

    var a = this.serializeArray();

    var $radio = $('input[type=radio],input[type=checkbox]', this);

    var temp = {};

    $.each($radio, function () {

        if (!temp.hasOwnProperty(this.name))

        {

            if ($("input[name='" + this.name + "']:checked").length == 0)

            {

                temp[this.name] = "";

                a.push({name: this.name, value: "off"});

            }

        }

    });

    return a;

};

 

三、使用js操作DOM實現局部刷新:

實現局部刷新的途徑:

1、假設頁面有查詢form和結果table

2、點擊查詢form的提交,觸 發js自定義的submit事件,在submit函數中對獲取的表單數據檢測後如果符合要求就傳遞給控制器,控制器從資料庫獲取結果數組後返回給ajaxsuccess。對返回給ajax的結果數組,可以創建一個refresh()函數,或直接在success中用jQuery(或其他js)操縱結果tableDOM),比如刪除tbody節點下的所有內容,並將結果數組格式化後添加到tbody下麵。

舉例:

//1php中的form表單

<div class="modal fade hide" id="add_engineer_modal" tabindex="-1" role="dialog">

......

<form id="add_engineer_modal_form" class="form-horizontal">

<fieldset>

......

<button type="button" class="btn btn-primary" id="add_engineer_modal_submit" onclick="add_engineer_modal_submit()" >提交更改</button>

......

</fieldset>

</form>

</div>

 

//2js校驗表單併發起ajax

function add_engineer_modal_check_value() {

    //edit_modal_check_value()為模板

    var serialize_array_object = $("#add_engineer_modal_form").mySerializeArray();

    var data = change_serialize_to_json(serialize_array_object);

    var check_results = [];

    check_results['result'] = [];//保存錯誤信息

    check_results['data'] = data;//保存inputselect對象

    //check_employee_number是自定義判斷員工號函數。

    if (check_employee_number(data['employee_number']) == false)

    {

        check_results['result'].push("請輸入有效的員工號(可選)");

    }

    return check_results;

}

 

function add_engineer_modal_submit() {

    var check_results = add_engineer_modal_check_value();

    if (check_results['result'].length == 0)

    {

        var json_data = JSON.stringify(check_results['data']);   //JSON.stringify() 方法將一個JavaScript值轉換為一個JSON字元串(ajax要求json對象或json字元串才能傳輸)

        $.ajax({

            type: 'POST',

            url: add_engineer_url, //php中全局定義url,方便使用thinkphpU方法

            data: {"json_data": json_data},            //ajax要求json對象或json字元串才能傳輸,json_data只是json字元串而已

            dataType: "json",

            success: function (data) {

                console.log("數據交互成功");

            },

            error: function (data) {

                console.log("數據交互失敗");

            }

        });

    }

    else

    {

        //彈出錯誤提示alert

    }

    return 0;

}

 

3、控制器返回數組給js

public function add_engineer() {

if (IS_AJAX)

{

$posted_json_data = I('post.json_data');

$posted_json_data_replace = str_replace('"', '"', $posted_json_data);

$posted_json_data_replace_array = (Array)json_decode($posted_json_data_replace);

   

   //處理資料庫事務寫入,通過判斷寫入結果來區分ajaxReturn的結果

  //可以將所有想要返回的數據放在一個數組中,比如新增的行id、插入資料庫的操作是否成功

  //如果操作資料庫成功就返回如下結果。

   $user_table->commit();

$data['result'] = true;

$data['pk_user_id'] = $data_add_user_result;

$this->ajaxReturn($data);

return 0;

}

}

改寫js

jsajax中,如果整個ajax正常交互,就會走success函數,否則會走error函數,一般情況下,error出現的原因都是傳輸的數據不符合要求。

success中的data就是ajaxReturn中傳輸的數組,舉例:

success: function (data) {

                if (data['result'] == false)

                {

                    alert(data['alert']);

                }

                else

                {

                    $('#add_engineer_modal').modal('hide');

                    $('#user_list_table tr').eq(0).after('<tr></tr>');

                    //這裡就可以使用data['pk_user_id']了。

                    $('#user_list_table tr').eq(1).append('<td>'+data['pk_user_id']+'</td>');

                }

            },

 

四、總結

整個過程是:

php中編寫頁面中的表單、提交按鈕等;

js中對php中的按鈕事件添加校驗和觸發函數,在js函數內,如果js對象的格式和內容正確就向控制器urlphp中初始化)發起ajax請求;

控制器中的相應操作響應ajax請求,並判斷數據後做資料庫讀寫操作,然後對資料庫操作結果做出判斷,ajaxReturn返回js需要的數組;

ajax成功返回時,jsajaxsuccess裡面使用js重寫(或初始化)需要顯示的信息。

這樣就完成了ajax非同步局部刷新。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 怎麼解決 Fiddler 抓包https配置 提示creation of the root certificate was not successful 證書安裝不成功 ...
  • C 是企業中廣泛使用的編程語言,特別是那些依賴微軟的程式語言。如果您使用C 構建應用程式,則最有可能使用Visual Studio,並且已經尋找了一些擴展來對您的開發進行管理。但是,這個工具列表可能會改變您編寫C 代碼的方式。 C 編程的最佳工具有以下幾類: "IDE" "VS擴展" "編譯器、編輯 ...
  • 設計原則:萬物皆對象 背景:在我的項目中,即需要與硬體通過Socket連接通訊,又需要給App提供Wcf服務操作介面,雖然都完成了,但是卻是一個控制台(雖然我很喜歡控制台,因為它簡單易用),把它放到伺服器運行,總有一個黑乎乎的視窗,總感覺不雅(原諒我的強迫症)。於是各種百度谷歌如何創建運行WIndo ...
  • 設計原則:萬物皆對象 背景:微軟提供了一套強大的通信框架Wcf,瞭解請看百度百科:ttps://baike.baidu.com/item/Wcf/7374854?fr=aladdin 雖然這套通信框架很強大,但是配置起來也不簡單,因此導致很多人望而卻步(包括我),我這人向來不喜歡麻煩,喜歡簡單,最好 ...
  • AOP為Aspect Oriented Programming的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的中統一處理業務邏輯的一種技術,比較常見的場景是:日誌記錄,錯誤捕獲、性能監控等 AOP的本質是通過代理對象來間接執行真實對象,在代理類中往往會添加裝飾一些額外的業務代 ...
  • 近期逆向一個程式,發現有保護措施,不能載入。用machoview後,發現有__RESTRICT段,因此改為RRSTRICT。 先前用iphone4調試,沒有問題,只是調試過程中老是卡死,要等個半天才能有反應。因此換了iphone5s,9.3.3。安裝後,把修改過的二進位scp到設備,發現閃退了。莫名 ...
  • 因為本人對web機制瞭解較少,在使用C/libcurl中遇到了很多問題。主要的解決方式: 1,在網頁源碼中找到提交form的定位。也就是網頁文件對應form中的action屬性。往往都是提交到jsp或者php等腳本中運行的,而不是直接提交到本網頁。 2,要註意http頭。http頭的不同會引起網頁的 ...
  • C++遠征之封裝篇(上)筆記 所有內容都是聽課筆記,願課堂視頻如下: C++遠征之封裝篇(上)-慕課網http://www.imooc.com/learn/382 類和對象 1 什麼是類,什麼是對象? 對象是具體的事物,而類是出於不同的目的從對象中抽象出來的,所以,同一事物可以抽象成不同的類。 舉個 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...