前端隐藏请求接口大法,JSONP

作者:zeke | 时间:Dec 11, 2024 3:32:56 PM | 访问量:4

<p><strong>JSONP</strong>(JSON with Padding)是一种传统的跨域请求技术,主要用于解决浏览器的同源策略限制,使得客户端能够从不同域名的服务器获取数据。JSONP 通过&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">&lt;script&gt;</code>&nbsp;标签加载并执行跨域响应中的 JavaScript 代码,通常返回的数据是一个 JavaScript 函数调用,函数的参数是 JSON 数据。</p><p><br></p><h3>JSONP 例子</h3><p>假设你有一个前端页面和一个后端 API,前端需要从后端 API 获取数据,但由于同源策略的限制,直接的 AJAX 请求无法成功。这时,可以使用 JSONP 作为替代方案。</p><p><br></p><h4>1. 后端 (Spring Boot) JSONP 支持</h4><p>首先,在 Spring Boot 后端,您需要创建一个支持 JSONP 的接口。Spring Boot 没有原生支持 JSONP,但可以通过手动构建响应来实现它。</p><p><br></p><pre class="ql-syntax" spellcheck="false">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 String callback) { // 创建一个简单的 JSON 响应 String jsonData = "{\"name\": \"John\", \"age\": 30}"; // 生成 JSONP 响应 return callback + "(" + jsonData + ")"; } } </pre><p>在上面的代码中,<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">/jsonp</code>&nbsp;接口会接收一个名为&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">callback</code>&nbsp;的查询参数。这个参数指定了客户端的回调函数,后端返回的 JSON 数据会作为该回调函数的参数。</p><p><br></p><h4>2. 前端 (HTML + JavaScript)</h4><p>前端使用&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">&lt;script&gt;</code>&nbsp;标签来加载 JSONP 数据。JavaScript 的回调函数会被用来处理返回的 JSON 数据。</p><p><br></p><pre class="ql-syntax" spellcheck="false">&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;JSONP Example&lt;/title&gt; &lt;script&gt; function handleResponse(data) { console.log("Received data:", data); document.getElementById("result").innerHTML = "Name: " + data.name + ", Age: " + data.age; } // 动态创建并加载 JSONP 请求 function loadJsonp() { var script = document.createElement('script'); script.src = "http://localhost:8080/jsonp?callback=handleResponse"; document.body.appendChild(script); } &lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;JSONP Example&lt;/h1&gt; &lt;button onclick="loadJsonp()"&gt;Load Data&lt;/button&gt; &lt;p id="result"&gt;&lt;/p&gt; &lt;/body&gt; &lt;/html&gt; </pre><h3>解释:</h3><ul><li><strong>后端</strong>:Spring Boot 后端的&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">/jsonp</code>&nbsp;接口会接收一个&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">callback</code>&nbsp;参数,并将其与 JSON 数据一起返回,格式为:<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">callback(JSON数据)</code>。</li><li><strong>前端</strong>:前端的 JavaScript 使用&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code>&nbsp;函数作为回调。通过动态创建一个&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">&lt;script&gt;</code>&nbsp;标签,向后端发送 JSONP 请求,并将返回的 JSON 数据传递给&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code>&nbsp;函数进行处理。</li><li class="ql-indent-1"><code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">script.src = "http://localhost:8080/jsonp?callback=handleResponse";</code>&nbsp;会向后端发起请求,后端返回的数据将会以&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code>&nbsp;函数的参数形式返回。</li><li class="ql-indent-1">由于 JSONP 是通过&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">&lt;script&gt;</code>&nbsp;标签进行跨域请求的,它不会受到浏览器同源策略的限制。</li></ul><h3>3. 请求和响应示例</h3><p>假设前端页面发起请求后,后端响应如下:</p><p><br></p><p><strong>请求 URL</strong>:</p><p><br></p><pre class="ql-syntax" spellcheck="false">http://localhost:8080/jsonp?callback=handleResponse </pre><p><br></p><p><strong>后端响应</strong>:</p><p><br></p><pre class="ql-syntax" spellcheck="false">handleResponse({"name": "John", "age": 30}); </pre><p><br></p><p>这时,前端会执行&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code>&nbsp;函数,并将响应数据作为参数传递给它,最终在页面上显示:</p><p><br></p><pre class="ql-syntax" spellcheck="false">Name: John, Age: 30 </pre><p><br></p><h3>注意事项</h3><ol><li><strong>安全性</strong>:JSONP 是一个相对不安全的技术,因为它通过&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">&lt;script&gt;</code>&nbsp;标签执行返回的数据,可能导致跨站脚本攻击(XSS)。因此,不建议在处理敏感数据时使用 JSONP。现代浏览器支持跨域资源共享(CORS),这是更安全的替代方案。</li><li><strong>CORS(跨域资源共享)</strong>:如果可能,建议使用 CORS 来解决跨域问题,它更加安全和标准化。JSONP 只适用于 GET 请求,并且不能发送复杂的数据结构(如请求体),而 CORS 支持更多类型的请求。</li><li><strong>缓存</strong>:JSONP 请求通常不支持缓存,这也是它的一个局限性。</li></ol><h3>总结</h3><p>JSONP 是一种通过&nbsp;<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">&lt;script&gt;</code>&nbsp;标签跨域请求数据的技术,适用于只需要发送简单的 GET 请求的场景,但由于其安全性问题,现在更多推荐使用 CORS 作为跨域解决方案。</p>