zoukankan      html  css  js  c++  java
  • 由“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等请求

  • 相关阅读:
    奇数
    简单的登录基于代码的
    偶数
    寻找特定的值
    'k1': 大于66的所有值, 'k2': 小于66的所有值
    差数和
    day1
    页面滑动监听
    jq的ajax初级使用
    在vue中引入swiper
  • 原文地址:https://www.cnblogs.com/langu/p/3557488.html
Copyright © 2011-2022 走看看