由“js跨域”想到"AJAX也不一定要XMLHttpRequest"


關鍵字:jsonp

jsonp的原理:同源約束限制了js腳本的跨域訪問,但是<script>和<iframe>的src標簽引用的js文件(只要響應正文是符合js語法的文本即可,不一定是js文件),沒有限制。

簡述:

瀏覽器端定義callback函數,名字可以隨意,暫且把它就叫callback,然后把改名字傳給跨域(剛好可以跨域,也可以是同域,即實現了非XMLHttpRequest也可以ajax),

服務器的響應正文,是callback函數的調用,注意整個正文都需要符合js語法,這樣巧妙的實現了跨域。

上代碼,自己寫的demo,在別人的代碼上有改進:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication2.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script type="text/javascript">
        var url = "http://www.a.com:8065/Handler1.ashx?c=callback";  //www.a.com本系統目錄的hosts中配置下即可,映射到127.0.0.1
        function p(src) {
            //參數r是避免ie瀏覽器的緩存,在IE中如果短時間請求相同的url,不會從服務器讀取,而是從緩存讀取
            var u = src + "&r=" + parseInt((Math.random() * 100000000000000000));
            var d = document.createElement("script");
            d.setAttribute("type", "text/javascript");
            d.src = u;
            document.body.appendChild(d);
        }

        function callback(d) { 
            document.getElementById("e").innerHTML = d;
        }

        window.onload = function () {
            p(url);
        };
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>test
        <span id="e"></span>
        <input type="button" value="重新請求" title="重新請求"  onclick="p(url)" />       
    </div>
    </form>
</body>
</html>

www.a.com:8066的handler1.aspx.cs的代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1
{
    /// <summary>
    /// Handler1 的摘要說明
    /// </summary>
    public class Handler1 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "application/javascript";//該值不影響結果
            var c=context.Request["c"];
            context.Response.Write(c + "('" +Guid.NewGuid().ToString()+ "')");//注意傳給callbak函數的參數,是js語法,所以要加引號
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

細節都在注釋中說明了

僅此備忘

ps:不能取代XMLHttpRequest的是,post和head等請求


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM