详解JS跨域原理及两种JSONP解决方案

作者:拾光时间:2026-10-29 18:35:30浏览:485

本文深入解析JavaScript跨域问题的根源——同源策略,并详细阐述利用Script标签src属性实现JSONP跨域的原理。通过对比两种具体方案:原生JS手动构造JSONP请求与jQuery封装的JSONP调用,展示了服务器端如何返回回调函数包裹的JSON数据,以及客户端如何解析响应,帮助开发者掌握解决跨域数据访问的核心技术。

什么是跨域

1.什么是跨域

在网页开发中,经常需要通过Ajax请求访问其他服务器的数据,此时客户端会遭遇跨域限制。

跨域问题的产生源于JavaScript语言安全机制中的同源策略。

同源策略规定,脚本只能读取与自身来源相同的窗口和文档属性。这里的“同一来源”由主机名、协议和端口号共同定义。

例如:

什么是跨域

实现原理

2.实现原理

在HTML DOM中,Script标签不受同源策略限制,可以跨域加载服务器上的脚本资源。因此,可以通过设置Script标签的src属性指向跨域URL,从而实现跨域数据访问。

例如:

直接获取JSON数据的方式不可行,但采用以下方法则可以实现。

服务器返回的数据格式有特定要求,不能仅返回纯JSON对象,如{“Name”:”zhangsan”}。

若服务器直接返回JSON字符串,客户端无法直接引用该数据。因此,服务器必须返回类似var json={“Name”:”zhangsan”}或json({“Name”:”zhangsan”})的形式,即数据需包裹在函数调用中。

为确保程序正常运行且不报错,客户端必须预先定义对应的JSON处理函数。

解决方案

3.解决方案

方案一 服务器端:


protected void Page_Load(object sender, EventArgs e)
  {
    string result = "callback({\"name\":\"zhangsan\",\"date\":\"2012-12-03\"})";

    Response.Clear();
    Response.Write(result);
    Response.End();
  }

客户端:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title></title>
  <script type="text/javascript">

    var result = null;
    window.onload = function () {
      var script = document.createElement("script");
      script.type = "text/javascript";
      script.src = "http://192.168.0.101/ExampleBusinessApplication.Web/web2.aspx";

      var head = document.getElementsByTagName("head")[0];
      head.insertBefore(script, head.firstChild);

    };

    function callback(data) {
      result = data;
    }

    function b_click() {
      alert(result.name);
    }
  </script>
</head>
<body>
  <input type="button" value="click me!" onclick="b_click();" />
</body>
</html>

方案二:通过jquery来完成

利用jQuery提供的JSONP功能。使用此方式时,服务器端需配合特定格式返回数据。

服务器端如下:


  protected void Page_Load(object sender, EventArgs e)
  {
    string callback = Request.QueryString["jsoncallback"];

    string result = callback + "({\"name\":\"zhangsan\",\"date\":\"2012-12-03\"})";

    Response.Clear();
    Response.Write(result);
    Response.End();
  }

客户端:


$.ajax({ 
        async: false, 
        url: "http://192.168.0.5/Web/web1.aspx", 
        type: "GET", 
        dataType: 'jsonp', 
        //jsonp的值自定义,如果使用jsoncallback,那么服务器端,要返回一个jsoncallback的值对应的对象. 
        jsonp: 'jsoncallback', 
        //要传递的参数,没有传参时,也一定要写上 
         data: null, 
        timeout: 5000, 
        //返回Json类型 
         contentType: "application/json;utf-8", 
        //服务器段返回的对象包含name,data属性. 
        success: function (result) { 
          alert(result.date); 
        }, 
        error: function (jqXHR, textStatus, errorThrown) { 
          alert(textStatus); 
        } 
      });

实际上,当执行这段JS代码时,浏览器向服务器发送了如下请求:

http://192.168.0.5/Web/web1.aspx?jsoncallback=jsonp1354505244726&_=1354505244742

服务器随后返回如下对象:

jsonp1354506338864({"name":"zhangsan","date":"2012-12-03"})

此时,跨域数据访问的需求得以满足。

以上就是关于js跨域原理以及2种解决方案介绍,希望对大家学习跨域知识点有所帮助,大家也可以结合其他相关文章进行学习研究。

作者最新文章