JSONP原理

本文介绍了一种利用JSONP实现跨域请求的方法。通过创建script标签并设置回调函数来接收服务器返回的数据,实现了从不同域获取JSON格式数据的功能。文章提供了具体的JavaScript代码示例。

<button id="btn">click</button>

<script type="text/javascript">

    function $(str){

        return document.getElementById(str)

    }

    function CreateScript(src) {

        var Scrip=document.createElement('script');

        Scrip.src=src;

        document.body.appendChild(Scrip);

    }

    function jsonpcallback(json) {

            console.log(json);//Object { email="中国", email2="中国222"}

    }

    $('btn').onclick=function(){

      CreateScript("http://localhost:51335/somejson?callback=jsonpcallback")    

    }

</script>

<think> 我们正在讨论JSONP原理和使用方法。根据用户提供的引用,我们需要整合信息并清晰地解释JSONP。 首先,JSONPJSON with Padding)是一种解决跨域问题的技术,它利用了<script>标签可以跨域加载资源的特性。 原理: 1. 由于浏览器的同源策略,通常无法跨域请求数据。但是<script>标签的src属性可以跨域加载资源。 2. JSONP通过在客户端定义一个全局回调函数,然后将函数名作为参数传递给服务器。 3. 服务器收到请求后,将数据包装在这个回调函数的调用中,返回一段JavaScript代码,例如:`callbackFunction({"data": "value"});` 4. 客户端加载这个脚本后,就会执行该函数,从而获取到数据。 使用方法: 1. 客户端(浏览器)需要先定义一个全局函数作为回调函数。 2. 动态创建一个<script>标签,将其src属性设置为请求的URL,并在URL中指定回调函数的名称(例如:`?callback=myCallback`)。 3. 服务器端接收到请求,根据回调函数名生成相应的JavaScript代码并返回。 4. 当脚本加载完成后,回调函数被调用,并传入服务器返回的数据。 示例代码(简化版): 引用[3]中提供了一个简化版的JSONP实现: ```javascript function simpleJsonp(url, callback) { // 生成唯一的函数名,避免冲突 const functionName = 'jsonp_' + Date.now() + Math.round(Math.random() * 1000); // 注册全局回调 window[functionName] = function(response) { callback(response); // 清理工作:移除script标签,删除全局函数 document.body.removeChild(script); delete window[functionName]; }; // 创建script标签 const script = document.createElement('script'); // 设置src,将回调函数名作为参数传递给服务器 script.src = url + (url.includes('?') ? '&' : '?') + 'callback=' + functionName; // 错误处理 script.onerror = function() { callback(new Error('JSONP请求失败')); document.body.removeChild(script); delete window[functionName]; }; // 将script标签添加到文档中,开始请求 document.body.appendChild(script); } ``` 另外,引用[2]中展示了使用jQuery进行JSONP请求的示例: ```html <script type="text/javascript"> $(document).ready(function(){ $.ajax({ type: "get", async: false, url: "http://www.practice-zhao.com/student.php?id=1", dataType: "jsonp", jsonp: "callback", // 指定回调函数名的参数名,默认为"callback" jsonpCallback: "jsonhandle", // 指定回调函数名,如果不指定,jQuery会自动生成 success: function(data) { alert("age:" + data.age + "name:" + data.name); } }); }); </script> ``` 优缺点(引用[3]): 优点: - 兼容性好:支持老版本浏览器 - 简单易用:实现相对简单 - 绕过同源策略:解决跨域问题 缺点: - 仅支持GET请求 - 安全性问题:可能遭受XSS攻击 - 错误处理困难 - 全局污染:需要在全局定义回调函数 总结: JSONP是一种利用<script>标签实现跨域数据请求的技术。它通过动态创建script标签,将服务器返回的数据作为回调函数的参数来执行。尽管现在有更现代的跨域解决方案(如CORS),但JSONP在特定场景下仍然有其价值。 根据用户要求,我们还需要生成相关问题: §§相关问题§§ 1. JSONP为什么只能使用GET请求? 2. 如何防止JSONP请求中的安全风险? 3. JSONP和CORS有什么区别? 4. 除了JSONP,还有哪些跨域请求的方法? 5. 服务器端如何支持JSONP? </think> ### JSONP原理及使用方法 #### JSONP原理 JSONPJSON with Padding)是一种利用`<script>`标签实现跨域数据请求的技术,核心原理如下: 1. **跨域限制绕过**:浏览器同源策略限制脚本跨域访问,但允许加载外部脚本资源。JSONP通过动态创建`<script>`标签的`src`属性发起请求(例如:`<script src="https://api.com/data?callback=handleResponse">`),绕过同源策略限制[^1][^3][^5]。 2. **回调机制**:客户端预先定义全局回调函数(如`handleResponse`),服务器将数据包裹在该函数调用中返回。例如服务器返回:`handleResponse({"name":"Alice","age":28})`,浏览器将其作为脚本执行,触发回调函数处理数据[^1][^4][^5]。 3. **数据格式**:服务器需配合将JSON数据包装成函数调用格式(Padding),而非纯JSON[^3][^4]。 #### JSONP实践方法 ##### 原生JavaScript实现 ```javascript function jsonpRequest(url, callback) { // 生成唯一回调函数名避免冲突 const callbackName = 'jsonp_' + Date.now(); // 定义全局回调函数 window[callbackName] = data => { callback(data); delete window[callbackName]; // 清理全局函数 document.body.removeChild(script); }; // 创建script标签 const script = document.createElement('script'); script.src = `${url}?callback=${callbackName}`; // 错误处理 script.onerror = () => { callback(new Error('JSONP请求失败')); cleanUp(); }; document.body.appendChild(script); } // 使用示例 jsonpRequest('https://api.com/data', data => { console.log('收到数据:', data); }); ``` ##### jQuery 实现 ```html <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $.ajax({ url: "https://api.com/data", dataType: "jsonp", // 指定JSONP类型 jsonp: "callback", // 回调参数名(默认callback) jsonpCallback: "handleData",// 自定义回调函数名 success: data => { console.log("姓名:", data.name, "年龄:", data.age); }, error: err => { console.error("请求失败", err); } }); </script> ``` #### 服务器端配合示例(PHP) ```php <?php $data = ['name' => 'Bob', 'age' => 32]; $callback = $_GET['callback']; // 获取客户端回调函数名 header('Content-Type: application/javascript'); echo $callback . '(' . json_encode($data) . ')'; // 返回函数调用 ?> ``` #### ⚠️ 注意事项 1. **仅支持GET请求**:JSONP本质是脚本加载,不支持POST/PUT等方法[^3][^4]。 2. **安全性风险**:需防范XSS攻击,确保信任服务器来源[^3]。 3. **错误处理**:通过`script.onerror`捕获网络错误,但HTTP状态码错误无法直接获取[^3]。 #### 🔄 适用场景 - 兼容老旧浏览器(如IE8)的跨域请求 - 获取公开API数据(如天气、股票等) - 快速原型开发[^1][^3] > JSONP作为传统跨域方案,在现代开发中逐渐被CORS替代,但在特定场景仍有应用价值[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值