前端隐藏请求接口大法,JSONP
作者:zeke | 时间:Dec 11, 2024 3:32:56 PM | 访问量:4
<p><strong>JSONP</strong>(JSON with Padding)是一种传统的跨域请求技术,主要用于解决浏览器的同源策略限制,使得客户端能够从不同域名的服务器获取数据。JSONP 通过 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);"><script></code> 标签加载并执行跨域响应中的 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> 接口会接收一个名为 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">callback</code> 的查询参数。这个参数指定了客户端的回调函数,后端返回的 JSON 数据会作为该回调函数的参数。</p><p><br></p><h4>2. 前端 (HTML + JavaScript)</h4><p>前端使用 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);"><script></code> 标签来加载 JSONP 数据。JavaScript 的回调函数会被用来处理返回的 JSON 数据。</p><p><br></p><pre class="ql-syntax" spellcheck="false"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP Example</title>
<script>
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);
}
</script>
</head>
<body>
<h1>JSONP Example</h1>
<button onclick="loadJsonp()">Load Data</button>
<p id="result"></p>
</body>
</html>
</pre><h3>解释:</h3><ul><li><strong>后端</strong>:Spring Boot 后端的 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">/jsonp</code> 接口会接收一个 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">callback</code> 参数,并将其与 JSON 数据一起返回,格式为:<code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">callback(JSON数据)</code>。</li><li><strong>前端</strong>:前端的 JavaScript 使用 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code> 函数作为回调。通过动态创建一个 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);"><script></code> 标签,向后端发送 JSONP 请求,并将返回的 JSON 数据传递给 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code> 函数进行处理。</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> 会向后端发起请求,后端返回的数据将会以 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code> 函数的参数形式返回。</li><li class="ql-indent-1">由于 JSONP 是通过 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);"><script></code> 标签进行跨域请求的,它不会受到浏览器同源策略的限制。</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>这时,前端会执行 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);">handleResponse</code> 函数,并将响应数据作为参数传递给它,最终在页面上显示:</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 是一个相对不安全的技术,因为它通过 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);"><script></code> 标签执行返回的数据,可能导致跨站脚本攻击(XSS)。因此,不建议在处理敏感数据时使用 JSONP。现代浏览器支持跨域资源共享(CORS),这是更安全的替代方案。</li><li><strong>CORS(跨域资源共享)</strong>:如果可能,建议使用 CORS 来解决跨域问题,它更加安全和标准化。JSONP 只适用于 GET 请求,并且不能发送复杂的数据结构(如请求体),而 CORS 支持更多类型的请求。</li><li><strong>缓存</strong>:JSONP 请求通常不支持缓存,这也是它的一个局限性。</li></ol><h3>总结</h3><p>JSONP 是一种通过 <code style="color: rgb(199, 37, 78); background-color: rgb(249, 242, 244);"><script></code> 标签跨域请求数据的技术,适用于只需要发送简单的 GET 请求的场景,但由于其安全性问题,现在更多推荐使用 CORS 作为跨域解决方案。</p>