JavaScript實現jsonp&&CORS

(function (global) {
    var id = 0, container = document.head || document.getElementsByTagName('head')[0];

    function jsonp(options) {
        if (!options || !options.url) return;
        var scriptNode = document.createElement("script"),
            url = options.url,
            data = options.data || {},
            callback = options.callback,
            fnName = 'jsonp' + id++;
        //添加回調函數
        data["callback"] = fnName;
        //拼接Url
        var params = [];
        for (var key in data) {
            params.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
        }

        url = url.indexOf("?") > 0 ? (url + "&") : (url + "?");
        url += params.join("&");
        scriptNode.src = url;

        //傳遞的是一個匿名的回調函數,須要執行,暴露爲一個全局方法
        global[fnName] = function (ret) {
            callback && callback(ret);
            // container.removeChild(scriptNode);
            delete global[fnName];
        };

        //出錯處理
        scriptNode.onerror = function (ev) {
            callback && callback({error: "error"});
            container.removeChild(scriptNode);
            global[fnName] && delete global[fnName]
        };
        scriptNode.type = "text/javascript";
        container.appendChild(scriptNode)
    }

    global.jsonp = jsonp;

})(this);

 

//1.直接添加如下兩行
header
("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept") //2.來自於stackoverflow的cors方法 function cors() { // Allow from any origin if (isset($_SERVER['HTTP_ORIGIN'])) { // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one // you want to allow, and if so: header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); // cache for 1 day } // Access-Control headers are received during OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); } }

 

  JSONP,利用了src引用靜態資源時不受跨域限制的機制,在客戶端定義一個回掉函數作數據接收處理,把回掉函數名告知服務器,服務端須要按照JavaScript的語法把數據放到約定好的回調函數之中。javascript

  CORS,依附於Ajax,經過添加HTTP Header部分字段請求與獲取有權限訪問的資源。CORS對開發者透明,瀏覽器會自動根據請求的狀況(簡單和複雜)作出不一樣的處理。CORS須要服務器支持。html

優缺點:java

  1. JSONP的主要優點是瀏覽器支持較好,IE10如下不支持CORSjson

  2. JSONP只能用於獲取資源(GET),CORS支持全部類型的HTTP請求。跨域

  3. JSONP錯誤處理機制並不完善,沒法進行錯誤處理,CORS能夠經過監聽onerror監聽錯誤,瀏覽器控制檯會看到報錯信息。瀏覽器

  4. JSONP只會發一次請求;對於複雜請求,CORS會發兩次請求。服務器

  5. JSONP存在callback參數注入和資源訪問受權設置。app

 

CORS參考:http://www.ruanyifeng.com/blog/2016/04/cors.htmlcors

相關文章
相關標籤/搜索