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等请求

  • 相关阅读:
    Linux-C基础知识学习:C语言作业-将5个学生成绩保存在一个数组中,单独实现一个计算平均成绩的average函数, 在main函数中获取该函数返回的平均值,并打印。
    Linux-C基础知识学习:C语言作业-输入两个数,将两个数交换,按升序输出。
    C语言学习:结构体(笔记)--未完待续
    C语言学习:结构体(笔记)
    PHP之函数
    PHP之流程控制
    PHP之常量和变量
    PHP之数据类型
    PHP之标记风格和注释
    VMware虚拟机中各类文件作用详解
  • 原文地址:https://www.cnblogs.com/langu/p/3557488.html
Copyright © 2011-2022 走看看