在介绍JSONP之前,我们先介绍一下浏览器的同源策略。
同源政策
同源策略是网景(Netscape)提出的一项众所周知的安全策略,所有支持JavaScript的浏览器都支持该策略。
所谓同源是指相同的域名、协议、端口。例如https://it-kiso.com:80/,其中it-kiso.com为域名,http为协议,80为端口(注:80为默认端口,可省略) ,对于不同的端口,您将需要查看定义)。
出于安全原因,浏览器不允许跨域请求。通过Ajax在网页和服务器之间发送和接收数据时,必须保证网页和请求的地址来自同源。否则,请求将不会成功。例如,https://it-kiso.com/下的网页只能与https://it-kiso.com/下的程序交互,但https://www.yahoo.co下则无法与jp交互。 /。以下程序进行交互。
同源策略可防止 JavaScript 脚本从您的网站读取数据并将其发送到其他网站。如果没有同源策略,恶意程序更有可能从您的网站泄露内容。
虽然同源策略在一定程度上提高了网站的安全性,但也给程序员带来了一些问题,比如访问开发接口时,可能会因为同源策略的存在而导致调用失败。解决这个问题就需要用到跨域,跨域的方法有很多,但最经典的就是JSONP。
JSONP的正式名称是“JSON with Padding”,翻译过来就是“带有回调的JSON”,是一种使用JSON的模式。通过JSONP,可以绕过浏览器的同源策略,进行跨域请求。
进行Ajax请求时,由于同源策略,无法进行跨域请求,但是可以使用<script>标签的src属性来加载跨域JavaScript脚本,因此可以利用该特性来加载JSONP已实施。与常规的Ajax请求不同,当使用JSONP进行跨域请求时,服务器不会返回JSON格式的数据,而是返回一段JavaScript代码,调用src属性中调用的函数来实现跨域返回。的部分。 。
JSONP的优点是兼容性高,可以运行在一些较旧的浏览器中,但缺点也非常明显。也就是说,您只能发出 GET 请求。
如何实现 JSONP
假设您想从网站 localhost:8080 向 localhost:8081 下的服务器发送请求。服务器返回以下内容:
{“name”:”IT 基金会”, “url”:”https://it-kiso.com/”}
如果直接发送Ajax请求,由于网站和服务器来源不同,同源策略会阻止该请求。示例代码如下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<div id="result"></div>
<button type="button" onclick="sendAjax()">送信</button>
<script>
function sendAjax() {
// XMLHttpRequestオブジェクトの作成
var request = new XMLHttpRequest();
// リクエストオブジェクトのインスタンス化
request.open("GET", "http://localhost:8081/test.php");
// readyStateの変化を監視
request.onreadystatechange = function() {
// リクエストが成功したかどうかを確認
if(this.readyState === 4 && this.status === 200) {
// サーバーからの応答を現在のページに挿入
document.getElementById("result").innerHTML = this.responseText;
}
};
// サーバーにリクエストを送信
request.send();
}
</script>
</body>
</html> 单击页面上的“提交请求”按钮会返回以下错误:
从“http://localhost:8081/test.php”处的源“http://localhost:8080”访问 XMLHttpRequest 被 CORS 策略阻止:“Access-Control-Allow-Origin”标头是请求的资源。
http://localhost:8081/test.php 获取 net::ERR_FAILED
如果您想成功从服务器检索数据,可以使用上面介绍的 JSONP 来实现。实施步骤如下:
使用<script>标签,将该标签的 src 属性设置为您请求的地址,如下所示:
<script src=”http://localhost:8081/test.php”></script>
此时可以看到<script>标签会自动解析并执行返回的内容,如果内容不是完整的JavaScript代码,程序就会报错,因此,JSONP跨域请求如果这样做的话,就会报错。必须确保服务器返回完整的JavaScript代码。
另外,JSON数据会自动转换为JavaScript对象,因此返回的内容不能是纯JSON数据,但如果不分配给变量或传递给函数则无法使用。
因此,您可以向请求提供一个回调函数(作为参数传递的函数,相当于一般函数),通过服务器返回该函数,并在<script>标签中使用返回的 JSON 数据时自动调用。被解析并执行。示例代码如下。
<script src=”http://localhost:8081/test.php?callback=showJsonData”></script>
服务器 http://localhost:8081/ 的完整代码是:
'IT基礎', 'url'=>'https://it-kiso.com/'); // 戻り値として返す内容を含む配列を定義
$callback = $_GET['callback']; // コールバック関数をリクエストから受信
echo $callback."(".json_encode($data).")"; // 上記の配列をJSON形式に変換し、関数に引数として連結してフロントエンドに返す
return; // 以降の処理を停止する
?> 网站 localhost:8080 的完整代码是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<script>
function showJsonData(data){
console.log(data);
}
</script>
<script src="http://localhost:8081/test.php?callback=showJsonData"></script>
</body>
</html> 运行结果为:
{名称:’IT 基金会’,网址:’https://it-kiso.com/’}

JSONP允许您绕过浏览器的同源策略并进行跨域请求。 JSONP是通过HTML标签的src属性来引用不受同源策略约束的资源来实现的。实施步骤如下:
- 将回调函数拼接到请求地址上,得到一个新地址,并将这个新地址赋给<script>标签的src属性。
- 服务器接收这个回调函数,将参数插入到函数中,然后以字符串的形式返回函数及其参数。
- <script> 当它收到返回的内容时,会将其视为 JavaScript 代码的一部分并自动执行。
注意:服务器返回的内容必须是可执行的JavaScript代码,而不是其他内容。




![2021 年如何设置 Raspberry Pi Web 服务器 [指南]](https://i0.wp.com/pcmanabu.com/wp-content/uploads/2019/10/web-server-02-309x198.png?w=1200&resize=1200,0&ssl=1)

