JSONP跨域原理与Node.js实现详解

作者:慢半拍时间:2026-10-22 17:49:55浏览:204

本文详细解析JSONP解决跨域问题的原理,利用script标签src属性不受同源策略限制的特性。通过Node.js搭建本地服务器,演示从手动创建回调函数到jQuery封装的完整JSONP调用流程,帮助开发者理解并应用这一经典跨域方案。

JSONP跨域原理与Node.js实现详解

JSONP 技术主要用于解决跨域数据获取的问题。在深入探讨其机制之前,有必要先厘清它与标准 JSON 格式之间的区别。

JSON与JSONP的区别

什么是JSON?

JSON 是一种基于文本的数据交换格式,也可视为一种数据描述标准。

它具有以下显著优点:

1、作为纯文本格式,跨平台传输极为简便;

2、JavaScript 原生支持,且后端主流语言几乎全部提供支持;

3、属于轻量级数据格式,字符占用极少,非常适合互联网传输场景;

4、具备较好的可读性,虽然不如 XML 直观,但在合理缩进后易于识别;

5、易于编写和解析,前提是需要了解其数据结构;

JSON 也存在缺点,例如无法直接处理跨域数据获取,而 JSONP 的出现正是为了弥补这一缺陷。

什么是JSONP?

JSONP 是一种由开发者利用创意实现的非官方跨域数据交互协议,其本质是利用了 JavaScript 文件的特性。

JSONP客户端实现原理

JSONP的客户端具体实现

  • 在 Web 页面中调用 JavaScript 文件时,不受跨域限制(事实上,任何拥有 "src" 属性的标签如 <script>、<img>、<iframe> 均具备跨域能力);
  • 对于跨域 JavaScript 文件中的代码(只要符合 Web 脚本安全策略),Web 页面可以无条件执行。

Node.js服务器搭建与手动JSONP示例

接下来将通过具体实例解释 JSONP 的原理,首先请确保电脑上已安装 nodejs。

1.建立本地 web 服务器

新建文件夹 jsonp,进入该文件夹后打开命令行工具。


npm install koa koa-static

新建 index.js 文件。


// index.js
const Koa = require('koa')
const app = new Koa()
app.use(require('koa-static')(__dirname + '/public'))
app.listen(3000)

2.新建 public 文件夹并进入,创建 index.html 和 somejsonp.js 文件。


// index.html
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
 <script>
  var localHandler = function(data){
   alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
  };
 </script>
 <script type="text/javascript" src="./somejsonp.js"></script>
</body>
</html>

// somejsonp.js
localHandler({"result":"我是远程js带来的数据"});

3.然后回到 jsonp 文件夹,输入命令 node index.js 后,用浏览器打开 http://localhost:3000 即可看到浏览器窗口弹出 js 文件中的 result,也就是我们获取到了 js 的数据。这便是jsonp的基本原理。

动态获取 JSONP 的数据,就是在页面中动态插入一段 script 标签,scr 中包含路径及参数,这样后台可根据参数动态生成 JS 文件,涉及后台实现,这里不做过多阐述。

jQuery中的JSONP封装

JSONP 在 JQuery 中的具体实现

jquery 中对于 jsonp 的封装也是基于以上原理,下面是基于 jquery 的代码。

修改index.html


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
 <script>
  $.ajax({
    url: 'http://localhost:3000/somejsonp.js',
    dataType: "jsonp",
    jsonp: "callback",
    jsonpCallback: "localHandler",
    success: function (data) {
     alert(data.result)
    }
  }) 
 </script>
</body>
</html>

jquery 动态生成script标签,并定义好方法。前提是jsonpCallback的方法名与引入的js文件方法名一致。

重新刷新页面即可看到弹出框中获取的 jsonp 中的数据。

简单描述就是——先定义一个方法,然后引入外部JS调用这个方法并携带数据。

动态创建Script标签的具体示例

具体示例

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。 而JSONP就是通过script节点中的src属性调用跨域的请求。当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用客户端回调函数。

前端


<!DOCTYPE html>
<head>
  <title>jsonp</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
  //动态创建script标签,并请求
  function addScriptTag(src){
    var script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.src = src;
    document.body.appendChild(script);
  };
  //在onload后,跨域请求
  window.onload = function(){
    addScriptTag('http://127.0.0.1:8080/jsonp?callback=test');
  };
  //回调函数,必须为全局,不然会报错
  function test(data){
    alert(data.name);
  };
</script>
</body>
</html>

搭建node server


//告诉Node.js引入http模块给该服务器应用使用
var http = require('http');
//引入url模块解析url字符串
var url = require('url');
//引入querystring模块处理query字符串
var querystring = require('querystring');
//创建新的HTTP服务器
var server = http.createServer();
//通过request事件来响应request请求
server.on('request',function(req, res){
  var urlPath = url.parse(req.url).pathname;
  var qs = querystring.parse(req.url.split('?')[1]);
  if(urlPath === '/jsonp' && qs.callback){
    res.writeHead(200,{'Content-Type':'application/json;charset=utf-8'});
    var data = {
      "name": "Monkey"
    };
    data = JSON.stringify(data);
    var callback = qs.callback+'('+data+');';
    res.end(callback);
  }
  else{
    res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});
    res.end('Hell World\n');
  }
});
//监听8080端口
server.listen('8080');
//用于提示我们服务器启动成功
console.log('Server running!');

运行node server之后,在浏览器打开上面所写的html页面,运行结果为:

JSONP跨域原理与Node.js实现详解

以上就是对于 JSONP 的简洁描述,希望对你有帮助。也希望大家多多支持本站。

作者最新文章