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

posted @   二师弟tl  阅读(2922)  评论(8编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示