Node.js 实现 JSONP 跨域请求实战教程

作者:终端旅客时间:2026-10-22 01:58:09浏览:113

本文详解基于 Node.js 的 JSONP 跨域请求实现。首先解析同源策略对 AJAX 的限制,阐述利用 script 标签 src 属性规避限制的原理。接着展示如何编写 Node 服务器解析 URL 和 QueryString 动态处理回调函数,并提供前端 HTML 及动态创建 script 元素的完整代码示例,帮助开发者掌握经典跨域解决方案。

JSONP 原理与同源策略限制

一、前言:

浏览器的安全机制核心在于同源策略。该策略要求资源访问必须满足三个条件一致:

1、协议相同;

2、域名相同;

3、端口相同。

然而,同源策略在保障安全的同时,也限制了 AJAX 进行跨域数据请求。为了突破这一限制,JSONP 成为一种常见的解决方案。

JSONP 的核心原理是利用 <script> 标签的 src 属性发起数据请求,该行为不受同源策略约束(<img> 和 <iframe> 的 src 同理)。服务器接收请求后,将数据封装在指定的回调函数名中返回给前端。

通过这种方式,即可实现跨域信息交互。

具体流程如下图所示:

JSONP 原理与同源策略限制 

理解 JSONP 的基本思路后,接下来我们将使用 Node.js 搭建一个简单的服务器,并配合前端代码,逐步完成一次完整的 JSONP 跨域请求实践。

Node.js 服务器搭建与路由处理

二、搭建 Node Server:

前端实现跨域请求需要后端配合。在此示例中,我们使用 Node.js 来模拟后台服务器环境。

因此,你需要具备基本的 Node.js 知识及开发环境。

下面开始编写一个简单的 Node 服务器。

首先,引入 http 模块以处理 HTTP 请求,并创建一个监听 8080 端口的 HTTP 服务器。

代码如下:


'use strict';
//通过require将http库包含到程序中
var http = require('http');
//创建新的HTTP服务器
var server = http.createServer();
//通过request事件来响应request请求
server.on('request',function(req, res){
  res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});
  res.end('Hell World\n');  
});
//监听8080端口
server.listen('8080');
//用于提示我们服务器启动成功
console.log('Server running!');

接着,为了区分 JSONP 请求与普通请求,服务器需要解析 URL 字符串。此处假设通过路径名 '/jsonp' 来识别 JSONP 请求。

代码如下:


'use strict';
//通过require将http库包含到程序中
var http = require('http');
//引入url模块解析url字符串
var url = require('url');
//创建新的HTTP服务器
var server = http.createServer();
//通过request事件来响应request请求
server.on('request',function(req, res){
  var urlPath = url.parse(req.url).pathname;
  //如果urlPath为'jsonp',就认定该请求为携带jsonp方法的http请求
  if(urlPath === '/jsonp'){
    res.writeHead(200,{'Content-Type':'application/json;charset=utf-8'});
    var data = {
      "name": "Monkey"
    };
    data = JSON.stringify(data);
    //假设我们定义的回调函数名为test
    var callback = 'test'+'('+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!');

上述代码第 19 行存在一个缺陷:回调函数名被硬编码。当判断为 JSONP 请求时,只能向前端传入固定的 'test',这显然不够灵活。

因此,我们需要引入 querystring 模块来处理查询字符串。

代码如下:


'use strict';
//通过require将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!');

至此,我们搭建好了所需的服务器。

服务器就绪后,接下来进行前端的跨域请求实现。

前端 JSONP 请求实现与动态脚本

三、JSONP 跨域请求之旅:

由于利用 <script> 标签的 src 发起请求,服务器约定在请求路径后添加 '/jsonp?callback' 即视为 JSONP 请求,且 callback 参数需携带前端已定义的全局方法名。

前端代码示例如下:


<!DOCTYPE html>
  <head>
    <title>jsonp</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  </head>
  <body>
    <script>
      function test(data){
        alert(data.name);
      };
    </script>
    <script src="http://127.0.0.1:8080/jsonp?callback=test"></script>
  </body>
</html>

前后端代码编写完毕后,我们来验证效果。

首先启动 Node 服务器,命令如下:

JSONP 原理与同源策略限制

注:示例中将服务器文件 server.js 存放于 D:/JSONP 目录。

随后运行上述 HTML 代码,可见请求成功并执行了 test 方法。

JSONP 原理与同源策略限制 

然而,页面加载即发起跨域请求可能并非最佳体验。我们可以动态创建 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=monkey');
};
//回调的方法,且必须为全局方法,不然会报错
function monkey(data){
  alert(data);
};

使用 JSONP 时需注意,回调函数必须是全局方法,否则会因为 script src 请求成功后立即执行而报错。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章