ajax封裝和跨域知識

ajax封裝和跨域知識

ajax 使用get仍是post

$_GET 是經過 URL 參數傳遞到當前腳本的變量數組。javascript

$_POST 是經過 HTTP POST 傳遞到當前腳本的變量數組。php

什麼時候使用 GET?

經過 GET 方法從表單發送的信息_對任何人都是可見的_(全部變量名和值都顯示在 URL 中)。GET 對所發送信息的數量也有限制。限制在大於 2000 個字符。不過,因爲變量顯示在 URL 中,把頁面添加到書籤中也更爲方便
GET 可用於發送非敏感的數據。
註釋:毫不能使用 GET 來發送密碼或其餘敏感信息!html

什麼時候使用 POST?

經過 POST 方法從表單發送的信息_對其餘人是不可見的_(全部名稱/值會被嵌入 HTTP 請求的主體中),而且對所發送信息的數量也_無限制_。java

此外 POST 支持高階功能,好比在向服務器上傳文件時進行 multi-part 二進制輸入。node

不過,因爲變量未顯示在 URL 中,也就沒法將頁面添加到書籤
提示:開發者偏心 POST 來發送表單數據。
接下來讓咱們看看如何安全地處理 PHP 表單!jquery

Name: <input type="text" name="name">
<span class="error">* <?php echo $nameErr;?></span>

與 POST 相比,GET 更簡單也更快,而且在大部分狀況下都能用。ajax

然而,在如下狀況中,請使用 POST 請求:數據庫

  • 沒法使用緩存文件(更新服務器上的文件或數據庫)
  • 向服務器發送大量數據(POST 沒有數據量限制)
  • 發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

按照要求封裝本身的ajax(原生非jquery)

引用自: SF

任務描述

學習Ajax,並嘗試本身封裝一個Ajax方法。實現以下方法:json

function ajax(url, options) {
    // your implement
}
// 使用示例:
ajax(
    'http://localhost:8080/server/ajaxtest', 
    {
        data: {
            name: 'simon',
            password: '123456'
        },
        onsuccess: function (responseText, xhr) {
            console.log(responseText);
        }
    }
);

options是一個對象,裏面能夠包括的參數爲:
type: post或者get,能夠有一個默認值
data: 發送的數據,爲一個鍵值對象或者爲一個用&鏈接的賦值字符串。使用=來鏈接鍵與值,使用&來鏈接多個請求參數
onsuccess: 成功時的調用函數
onfail: 失敗時的調用函數segmentfault

實現以下

/**
 * AJAX函數封裝
 * @param {string} url     請求地址(必須)
 * @param {object} options 發送請求的選項參數
 *   @config {string} [options.type] 請求發送的類型。默認爲GET。
 *   @config {Object} [options.data] 須要發送的數據。
 *   @config {Function} [options.onsuccess] 請求成功時觸發,function(oAjax.responseText, oAjax)。(必須)
 *   @config {Function} [options.onfail] 請求失敗時觸發,function(oAjax)。(oAJax爲XMLHttpRequest對象)
 *
 *@returns {XMLHttpRequest} 發送請求的XMLHttpRequest對象
 */
function ajax(url, options) {
    //1.建立ajax對象
    var oAjax = null;
        /**
         * 此處必須須要使用window.的方式,表示爲window對象的一個屬性.不存在時值爲undefined,進入else
         * 若直接使用XMLHttpRequest,在不支持的狀況下會報錯
         **/
    if (window.XMLHttpRequest) {
        //IE6以上
        oAjax = new XMLHttpRequest();
    } else {
        oAjax = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    //2.鏈接服務器
    //open(方法,url,是否異步)
    var param = ""; //請求參數。
    //只有data存在,且爲對象使才執行
    var data = options.data ? options.data : -1; //緩存data
    if (typeof (data) === "object") {
        for (var key in data) { //請求參數拼接
            if (data.hasOwnProperty(key)) {
                param += key + "=" + data[key] + "&";
            }
        }
        param.replace(/&$/, "");
    } else {
        param = "timestamp=" + new Date().getTime();
    }

    //3.發送請求
    var type = options.type ? options.type.toUpperCase() : "GET";
    if (type === "GET") {
        oAjax.open("GET", url + "?" + param, true);
        oAjax.send();
    } else {
        oAjax.open("POST", url, true);
        oAjax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        oAjax.send(param);
    }

    //4.接收返回
    //OnRedayStateChange事件
    oAjax.onreadystatechange = function () {
        if (oAjax.readyState === 4) {
            if (oAjax.status === 200) {
                //請求成功。形參爲獲取到的字符串形式的響應數據
                options.onsuccess(oAjax.responseText, oAjax);
            } else {
                //先判斷是否存在請求失敗函數
                //存在時,形參爲XMLHttpRequest對象,便於進行錯誤進行處理
                if (options.onfail) {
                    options.onfail(oAjax);
                }
            }
        }
    };
    return oAjax;//發送請求的XMLHttpRequest對象
}

跨域方式

ajax自己並不能跨域,要藉助其餘方式進行跨域。引用有 SF

get方式的jsonp跨域,能夠用jquery提供的$.ajax

可能平時最經常使用到的就是get方式的jsonp跨域,能夠用jquery提供的$.ajax 、$.getJSON。

$.ajax({
    url:'接口地址',
    type:'GET',
    data:'想給接口傳的數據',
    dataType:'jsonp',
    success:function(ret){
        console.log(ret);
    }
});

這樣很簡單的就能夠實現jsonp的跨域,獲取接口返回值。實現原理是利用script標籤跨域

post方式的form表單跨域。

a.com html:
<script>
function postCallback(data){}
</script>
<form acrion='接口連接' method='post' target='ifr'></form>
<iframe name='ifr'></iframe>
a.com callback.php:
<?php
header('Content-type: text/javascript');
echo '<script>';
//回調原頁面上函數處理返回結果
echo 'window.top.postcallback(' .$_GET['data']. ');';
echo '</script>';

b.com api.php:

<?php
//....
$data = '{"ret":0,"msg":"ok"}';
// ** 讓結果跳轉到a.com域 **
header("Location: http://a.com/callback.php?data=".urlencode($data));

CORS跨域

原理:CORS定義一種跨域訪問的機制,可讓AJAX實現跨域訪問。CORS 容許一個域上的網絡應用向另外一個域提交跨域 AJAX 請求。實現此功能很是簡單,只需由服務器發送一個響應標頭便可。

注:移動終端上,除了opera Mini都支持。

利用 CORS,http://www.b.com 只需添加一個標頭,就能夠容許來自 http://www.a.com 的請求,下圖是我在PHP中的 hander() 設置,「*」號表示容許任何域向咱們的服務端提交請求:

header("Access-Control-Allow-Origin:*");

也能夠設置指定域名:

header("Access-Control-Allow-Origin:http://www.b.com");

js部分:

$.ajax({
    url: a_cross_domain_url,
    crossDomain: true,
    method: "POST"
});

CORS比較適合應用在傳送信息量較大以及移動端來使用。

script標籤來跨域(有待補充調整)

<script src='訪問的接口地址'></script>
js.onload = js.onreadystatechange = function() {
    if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
        // callback在此處執行
        js.onload = js.onreadystatechange = null;
    }
};

h5的postMessage

otherWindow.postMessage(message, targetOrigin);
otherWindow: 對接收信息頁面的window的引用。能夠是頁面中iframe的contentWindow屬性;window.open的返回值;經過name或下標從window.frames取到的值。
message: 所要發送的數據,string類型。
targetOrigin: 用於限制otherWindow,「*」表示不做限制

a.com/index.html中的代碼:

<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
    var ifr = document.getElementById('ifr');
    var targetOrigin = 'http://b.com';  // 若寫成'http://b.com/c/proxy.html'效果同樣
                                        // 若寫成'http://c.com'就不會執行postMessage了
    ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script>

b.com/index.html中的代碼:

<script type="text/javascript">
    window.addEventListener('message', function(event){
        // 經過origin屬性判斷消息來源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 彈出"I was there!"
            alert(event.source);  // 對a.com、index.html中window對象的引用
                                  // 但因爲同源策略,這裏event.source不能夠訪問window對象
        }
    }, false);
</script>

六、子域跨域(document.domain+iframe)(h5中這個標籤已經被禁止了)

www.a.com上的a.html

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
    var doc = ifr.contentDocument || ifr.contentWindow.document;
    // 在這裏操縱b.html
    alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

script.a.com上的b.html

document.domain = 'a.com';

具體的作法是能夠在 http://www.a.com/a.htmlhttp://script.a.com/b.html兩... = 'a.com';而後經過a.html文件中建立一個iframe,去控制iframe的contentDocument,這樣兩個js文件之間就能夠「交互」了。固然這種辦法只能解決主域相同而二級域名不一樣的狀況。

相關文章
相關標籤/搜索