当前位置: 首页 > ds >正文

跨域解决方案之JSONP

目录

 

一、JSONP 核心原理

二、JSONP 实现步骤

(一)客户端代码

(二)服务器端代码(ASP.NET实现)

1. ASP.NET Web Forms 实现

2. ASP.NET Core 实现

三、JSONP 优缺点

(一)优点

(二)缺点

四、JSONP 适用场景


 

在 Web 开发领域,跨域问题始终是开发者需要攻克的难关。浏览器的同源策略严格限制了不同源(协议、域名、端口任意一项不同)之间的资源访问,导致 AJAX 请求无法直接获取跨域数据。JSONP(JSON with Padding)作为早期流行的跨域解决方案,利用<script>标签的特性巧妙绕过这一限制。虽然如今 CORS 已成为主流,但 JSONP 的原理与应用仍值得深入了解。

一、JSONP 核心原理

JSONP 的核心在于利用<script>标签不受同源策略限制的特性。在 HTML 中,<script>标签可以加载任意域名的 JavaScript 文件,浏览器会自动执行其中的代码。JSONP 将原本的 JSON 数据包裹在一个函数调用中,形成可执行的 JavaScript 代码,从而实现跨域数据传输。

具体流程如下:

  • 客户端定义回调函数:在页面中创建一个全局函数,用于接收和处理服务器返回的数据。
  • 动态发起请求:通过创建<script>标签,并将请求 URL 设置为src属性,其中包含指定的回调函数名参数。
  • 服务器响应包装:服务器接收到请求后,提取回调函数名,将数据以该函数调用的形式返回。
  • 浏览器执行代码:浏览器加载并执行<script>标签中的代码,自动调用回调函数,将数据传递给客户端。

二、JSONP 实现步骤

(一)客户端代码

以下是通过原生 JavaScript 实现的 JSONP 请求示例,包含按钮点击触发请求的逻辑:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JSONP Example</title>
</head>
<body><button id="fetchDataBtn">获取数据</button><div id="result"></div><script>function handleData(data) {console.log('Received data:', data);document.getElementById('result').innerHTML = JSON.stringify(data);}const fetchDataBtn = document.getElementById('fetchDataBtn');fetchDataBtn.addEventListener('click', function () {// 移除之前的script标签const existingScripts = document.querySelectorAll('script[src^="https://api.example.com/data?callback=handleData"]');existingScripts.forEach(script => script.remove());const script = document.createElement('script');const url = 'https://api.example.com/data?callback=handleData';script.src = url;document.body.appendChild(script);});</script>
</body>
</html>

在上述代码中:

  • 定义handleData回调函数,用于处理服务器返回的数据,并更新页面内容。
  • 为按钮添加点击事件监听器,每次点击时先移除已存在的用于该 JSONP 请求的<script>标签,避免标签冗余,再动态创建新的<script>标签发起请求。

(二)服务器端代码(ASP.NET实现)

1. ASP.NET Web Forms 实现

在ASP.NET Web Forms 项目中,可在WebForm1.aspx.cs文件中添加如下代码:

using System;
using System.Web;public partial class WebForm1 : System.Web.UI.Page
{protected void Page_Load(object sender, EventArgs e){string callback = Request.QueryString["callback"];if (!string.IsNullOrEmpty(callback)){var data = new { message = "This is data from ASP.NET server", code = 200 };string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(data);string jsonpResponse = $"{callback}({jsonData})";Response.ContentType = "application/javascript";Response.Write(jsonpResponse);Response.End();}}
}

上述代码中,首先获取 URL 中的callback参数,然后将数据序列化为 JSON 字符串,再将其包装在回调函数中,最后设置响应头并返回结果。

2. ASP.NET Core 实现

在ASP.NET Core 项目中,需先安装Newtonsoft.Json包,然后在Controllers文件夹下创建JsonpController.cs文件,代码如下:

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;namespace JsonpDemo.Controllers
{[Route("api/[controller]")][ApiController]public class JsonpController : ControllerBase{[HttpGet]public IActionResult GetData(){string callback = Request.Query["callback"];if (string.IsNullOrEmpty(callback)){return BadRequest("callback parameter is required");}var data = new { message = "This is data from ASP.NET Core server", code = 200 };string jsonData = JsonConvert.SerializeObject(data);string jsonpResponse = $"{callback}({jsonData})";return Content(jsonpResponse, "application/javascript");}}
}

在ASP.NET Core 的实现里,通过控制器接收请求,获取callback参数,包装数据后以指定的application/javascript类型返回 JSONP 响应。

三、JSONP 优缺点

(一)优点

  • 兼容性好:几乎支持所有浏览器,包括老旧版本,适用于对浏览器兼容性要求高的项目。
  • 实现简单:无需复杂的服务器配置和中间件,客户端和服务器端代码逻辑清晰,易于上手。

(二)缺点

  • 安全性低:由于允许加载任意来源的 JavaScript 代码,容易遭受跨站脚本攻击(XSS)。若服务器返回的内容被篡改,可能导致用户数据泄露。
  • 仅支持 GET 请求:受<script>标签请求方式限制,无法满足 POST、PUT 等其他请求类型的需求,不适用于数据提交场景。
  • 错误处理困难:缺乏像 AJAX 那样完善的错误处理机制,请求失败时难以准确捕获和处理错误信息,不利于调试。

四、JSONP 适用场景

尽管 JSONP 存在诸多局限性,但在某些场景下仍有其价值:

  • 老旧项目兼容:对于无法大规模重构的历史项目,为实现跨域功能且保证浏览器兼容性,JSONP 可作为过渡方案。
  • 简单数据查询:仅需从服务器获取数据,且对安全性要求不高的场景,如公开 API 的数据查询。

JSONP 作为早期的跨域解决方案,以独特的方式在 Web 开发历史中留下了印记。虽然随着技术发展,CORS 凭借更高的安全性和更全面的功能逐渐占据主导地位,但 JSONP 的原理和应用依然是开发者理解跨域技术演进的重要一环。

 

http://www.xdnf.cn/news/8440.html

相关文章:

  • YOLOV11改进策略【最新注意力机制】CVPR2025局部区域注意力机制LRSA-增强局部区域特征之间的交互
  • 使用DDR4控制器实现多通道数据读写(十三)
  • DAO模式
  • DEBUG设置为False 时,django默认的后台样式等静态文件丢失的问题
  • 新能源汽车滑行阻力参数计算全解析:从理论推导到MATLAB工具实现
  • macOS 安装 PostgreSQL
  • 基于大模型的股骨干骨折全周期预测与诊疗方案研究报告
  • 可视化大屏全屏后重载echarts图表
  • JUC并发编程1
  • MyBatis 笔记:parameterType、resultType 与 resultMap 的区别详解
  • Android 网络全栈攻略(四)—— 从 OkHttp 拦截器来看 HTTP 协议一
  • 146. LRU Cache
  • Anthropic公司近日发布了两款新一代大型语言模型Claude Opus 4与Claude Sonnet 4
  • 矩阵:线性代数在AI大模型中的核心支柱
  • 深入解析MySQL中的HAVING关键字:从入门到实战
  • Docker 与 Kubernetes 部署 RabbitMQ 集群(二)
  • C++ 忘掉std::cout吧,fmt和spdlog的结合
  • 达梦数据库-报错-01-[-3205]:全文索引词库加载出错
  • paddle 打包代码 ocr
  • 国产高云FPGA实现MIPI视频解码+图像缩放,基于OV5647摄像头,提供Gowin工程源码和技术支持
  • 04-jenkins学习之旅-java后端项目部署实践
  • 攻略生成模块
  • python邮件地址检验 2024年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析
  • C++---vector模拟实现
  • 黑马点评-实现安全秒杀优惠券(使并发一人一单,防止并发超卖)
  • Java桌面应用开发详解:自制截图工具从设计到打包的全流程【附源码与演示】
  • LVS + Keepalived + Nginx 高可用负载均衡系统实验
  • 详解Mysql的 Binlog、UndoLog 和 RedoLog
  • 「金融证券行业」 如何搭建自己的研发智能管理体系?
  • Linux 操作文本文件列数据的常用命令