网站敏感词汇,正规的招聘网站,长春建网站一般多少钱,域名怎么申请JSONP#xff08;JSON with Padding#xff09;是一种跨域数据交互技术#xff0c;虽然它不是真正的 AJAX 请求#xff0c;但可以实现类似的局部刷新效果。本文将深入解析 JSONP 的原理#xff0c;并通过完整的 Java 后端和 JavaScript 前端示例演示其工作流程。
一、JSO…JSONPJSON with Padding是一种跨域数据交互技术虽然它不是真正的 AJAX 请求但可以实现类似的局部刷新效果。本文将深入解析 JSONP 的原理并通过完整的 Java 后端和 JavaScript 前端示例演示其工作流程。
一、JSONP 的基本原理
传统的 AJAX 请求受同源策略限制而 JSONP 利用了script标签不受同源策略约束的特性。其核心流程如下
前端动态创建一个script标签src 指向跨域的 API 接口并添加一个回调函数名作为参数例如callbackhandleResponse服务器收到请求后将 JSON 数据包装在回调函数中返回例如handleResponse({name:John,age:30})当 script 标签加载完成后会执行这个回调函数从而获取到服务器返回的数据
二、完整代码实现
下面是一个完整的 JSONP 示例包含 Java 后端和 JavaScript 前端代码
jsonp-client.html
!DOCTYPE html
html
headtitleJSONP跨域请求示例/title
/head
bodyh3JSONP跨域请求演示/h3button onclickfetchData()获取跨域数据/buttondiv idresult/divscriptfunction fetchData() {// 生成唯一的回调函数名避免命名冲突const callbackName jsonpCallback_ Date.now();// 创建script标签const script document.createElement(script);// 定义回调函数window[callbackName] function(data) {// 处理返回的数据document.getElementById(result).innerHTML 姓名: ${data.name}, 年龄: ${data.age}, 城市: ${data.city};// 处理完成后移除script标签和回调函数document.body.removeChild(script);delete window[callbackName];};// 设置script的src指向跨域API并带上回调函数名script.src http://localhost:8080/jsonp?callback callbackName;// 错误处理script.onerror function() {document.getElementById(result).innerHTML 请求失败请检查服务器;document.body.removeChild(script);delete window[callbackName];};// 将script添加到页面中触发请求document.body.appendChild(script);}/script
/body
/html
JsonpServer.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;WebServlet(/jsonp)
public class JsonpServer extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应头response.setContentType(application/javascript);response.setCharacterEncoding(UTF-8);// 获取回调函数名String callback request.getParameter(callback);if (callback null || callback.isEmpty()) {response.getWriter().write(Invalid JSONP request);return;}// 模拟业务数据String jsonData {\name\:\John\,\age\:30,\city\:\New York\};// 构造JSONP响应callbackFunction(jsonData)String jsonpResponse callback ( jsonData );// 返回JSONP响应response.getWriter().write(jsonpResponse);}
}
三、代码解析 Java 后端 创建了一个 Servlet 处理 JSONP 请求从请求参数中获取回调函数名将 JSON 数据包装在回调函数中返回设置正确的 Content-Type 为application/javascript 前端实现 动态创建 script 标签并指定跨域 URL定义全局回调函数处理返回的数据请求完成后清理 DOM 和全局变量添加了错误处理机制
四、JSONP 的优缺点
优点
兼容性好支持所有主流浏览器实现简单不需要额外的服务器配置可以绕过同源策略限制
缺点
只支持 GET 请求存在安全风险JSONP 注入攻击错误处理相对复杂只适用于获取 JSON 数据
五、使用注意事项
确保对回调函数名进行严格的输入验证防止 XSS 攻击生产环境中应使用 HTTPS 协议考虑使用 CORS 作为更现代的跨域解决方案除非需要兼容非常旧的浏览器对返回的 JSON 数据进行适当的安全过滤
JSONP 虽然不是一个真正的 AJAX 请求但在特定场景下如需要兼容旧浏览器它仍然是一个有效的跨域解决方案。通过理解其原理和实现方式开发者可以在合适的场景下选择最佳的跨域策略。 六、实现类似的局部刷新效果怎么实现的
AJAX 请求依赖浏览器的 XMLHttpRequest 或 Fetch API受同源策略限制而 JSONP 借助 script 标签的跨域特性实现数据获取虽非真正的 AJAX却能达成局部刷新效果。以下是其核心实现逻辑与示例
1.JSONP 实现局部刷新的核心原理 利用 script 标签的跨域特性 浏览器中script 标签的 src 属性可请求任意域名的资源如 JavaScript 文件不受同源策略限制。JSONP 本质是动态加载一个包含数据的 JavaScript 脚本通过执行脚本中的函数来获取数据。 局部刷新的实现逻辑 前端动态创建 script 标签并发起请求服务器返回的脚本包含回调函数调用如 callback({data})。脚本加载完成后自动执行回调函数将数据渲染到页面指定区域无需刷新整个页面从而实现 “局部刷新”。 2.代码示例JSONP 实现局部刷新
前端页面HTML JavaScript
!DOCTYPE html
html
headtitleJSONP 局部刷新示例/title
/head
bodyh3JSONP 局部刷新演示/h3button onclickloadData()点击获取数据/buttondiv idcontent数据将显示在这里/divscriptfunction loadData() {// 生成唯一回调函数名避免冲突const callbackName jsonp_${Date.now()};// 定义回调函数挂载到 window 全局对象window[callbackName] function(response) {// 将数据渲染到页面实现局部刷新document.getElementById(content).innerHTML p姓名${response.name}/pp年龄${response.age}/pp内容${response.content}/p;// 清理回调函数和 script 标签document.body.removeChild(scriptElement);delete window[callbackName];};// 创建 script 标签并设置 srcconst scriptElement document.createElement(script);scriptElement.src http://localhost:8080/jsonp?callback${callbackName}param1;document.body.appendChild(scriptElement);}/script
/body
/html
Java 后端Spring Boot 示例
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;RestController
public class JsonpController {GetMapping(/jsonp)public String jsonp(RequestParam(callback) String callback) {// 构造数据String data {\name\:\JSONP示例\,\age\:1,\content\:\通过脚本加载实现局部刷新\};// 将数据包装在回调函数中返回JSONP 核心return callback ( data );}
}
3.局部刷新的实现关键点 动态渲染数据 回调函数接收到数据后通过 DOM 操作如 document.getElementById(content).innerHTML直接更新页面指定区域无需刷新整个页面。 脚本加载与执行流程 前端创建 script 标签并插入页面 → 浏览器发送 GET 请求到服务器。服务器返回 callback({data}) 格式的脚本 → 浏览器加载并执行脚本触发回调函数。回调函数更新页面 DOM完成局部刷新。 与 AJAX 的区别 特性AJAXXHR/FetchJSONP请求方式依赖 XMLHttpRequest依赖 script 标签跨域支持需服务器配置 CORS天然支持跨域请求类型支持 GET/POST 等仅支持 GET局部刷新实现通过 XHR 获取数据后渲染通过脚本执行回调函数渲染 七、script 标签的 src 属性确实会触发资源加载但不会导致页面跳转。
script 标签的 src 属性确实会触发资源加载但不会导致页面跳转。这是因为浏览器对不同类型的资源有不同的处理方式
1.核心原理script 加载不会跳转页面
当你使用 script src... 时浏览器会
异步加载指定的 JavaScript 文件默认不阻塞页面渲染除非设置了 defer 或 async。执行脚本内容但不会导航到新页面。脚本执行过程中可通过 DOM 操作更新页面的局部区域从而实现 “局部刷新”。
2.对比理解不同标签的行为差异
标签类型示例代码浏览器行为a 链接a hrefhttp://example.com点击后跳转至新 URL整个页面刷新。img 图片img srcimage.jpg加载图片资源并显示在页面指定位置不影响其他内容不跳转页面。script 脚本script srcscript.js加载 JavaScript 代码并执行允许通过脚本修改页面如更新某个 div 的内容不跳转页面。
3.JSONP 如何利用这一特性实现局部刷新
示例代码回顾
scriptfunction loadData() {const callbackName jsonp_${Date.now()};window[callbackName] function(data) {// 更新页面局部区域如 ID 为 content 的 divdocument.getElementById(content).innerHTML 姓名${data.name};};// 创建 script 标签const script document.createElement(script);script.src http://api.example.com/data?callback${callbackName};document.body.appendChild(script);}
/script
4.执行流程详解
动态创建 script 标签
const script document.createElement(script);
script.src http://api.example.com/data?callbackjsonp_12345;
document.body.appendChild(script); 浏览器发送 GET 请求到 http://api.example.com/data?callbackjsonp_12345。
服务器返回 JSONP 格式的脚本 服务器收到请求后返回如下内容注意这是一个 JavaScript 脚本
jsonp_12345({name: John,age: 30
});
浏览器执行脚本
脚本加载完成后浏览器执行 jsonp_12345(...) 函数。
由于这个函数已在前端定义window[callbackName] ...数据会被传递到回调函数中。
回调函数通过 document.getElementById(content).innerHTML 更新页面局部内容。
最终效果
页面没有跳转只有 #content 区域的内容被更新实现了 “局部刷新”。
5.关键区别导航 vs. 资源加载 导航Navigation 当用户点击链接a、在地址栏输入 URL、调用 window.location.href ... 时浏览器会加载新页面丢弃当前页面状态。 资源加载Resource Loading 当使用 script、img、link 等标签加载资源时浏览器仅获取指定资源并集成到当前页面中不会跳转。