JSONP


目录

    显示目录


JSONP是一种发送JSON数据而不用担心跨域问题的方法。

JSONP 不使用 XMLHttpRequest 对象。

JSONP 使用 <script> 标签代替。


JSONP简介

JSONP 代表带填充的 JSON。

由于跨域策略,从另一个域请求文件可能会导致问题。

从另一个域请求外部脚本不会出现此问题。

JSONP利用了这个优势,使用script标签请求文件 而不是 XMLHttpRequest 对象。

 <script src="demo_jsonp.php">

服务器文件

服务器上的文件将结果包装在 函数调用:

例子

 <?php
$myJSON = '{ "name":"John", "age":30, "city":"New York" }';
  
echo "myFunc(".$myJSON.");";
  ?>

结果返回对名为“myFunc”的函数的调用,其中 JSON 数据为 一个参数。

确保该函数在客户端存在。

JavaScript 函数

名为“myFunc”的函数位于客户端,并准备好处理 JSON 数据:

例子

 function myFunc(myObj) 
  {
  document.getElementById("demo").innerHTML = 
  myObj.name;
  }

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h2>Request JSON using the script tag</h2>
<p>The PHP file returns a call to a function that will handle the JSON data.</p>
<p id="demo"></p>

<script>
function myFunc(myObj) {
  document.getElementById("demo").innerHTML = myObj.name;
}
</script>

<script src="demo_jsonp.php"></script>

</body>
</html>


创建动态脚本标签

上面的示例将在页面打开时执行“myFunc”函数 加载,基于您放置脚本标记的位置,这不是很令人满意。

脚本标签应仅在需要时创建:

例子

单击按钮时创建并插入 <script> 标记:

 function clickButton() {
  let s = document.createElement("script");
  s.src = "demo_jsonp.php";
  document.body.appendChild(s);
  }

自己尝试一下 →

<!DOCTYPE html>
<html>

<body>

<h2>Click the Button.</h2>
<p>A script tag with a src attribute is created and placed in the document.</p>
<p>The PHP file returns a call to a function with the JSON object as a parameter.</p>

<button onclick="clickButton()">Click me!</button>

<p id="demo"></p>

<script>
function clickButton() {
  let s = document.createElement("script");
  s.src = "demo_jsonp.php";
  document.body.appendChild(s);
}

function myFunc(myObj) {
  document.getElementById("demo").innerHTML = myObj.name;
}
</script>

</body>
</html>

动态 JSONP 结果

上面的例子仍然是非常静态的。

通过将 JSON 发送到 php 文件来使示例动态化,并让 php 文件基于以下内容返回 JSON 对象 它获得的信息。

PHP文件

 <?php
header("Content-Type: application/json; charset=UTF-8");
$obj = 
  json_decode($_GET["x"], false);
  
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
  $result = $conn->query("SELECT name FROM 
  ".$obj->$table." LIMIT ".$obj->$limit);
$outp = array();
  $outp = $result->fetch_all(MYSQLI_ASSOC);
echo "myFunc(".json_encode($outp).")";
?>

PHP 文件解释:

  • 使用 PHP 函数将请求转换为对象 json_decode()

  • 访问数据库,并用请求的数据填充数组。

  • 将数组添加到对象。

  • 使用以下命令将数组转换为 JSON json_encode() 函数。

  • 将“myFunc()”包裹在返回对象周围。

JavaScript 示例

将从 php 文件调用“myFunc”函数:

const obj = { table: "products", limit: 10 };
let s = document.createElement("script");
s.src = "jsonp_demo_db.php?x=" + JSON.stringify(obj);
document.body.appendChild(s);

function myFunc(myObj) {
  let txt = "";
  for (let x in myObj) 
  {
    txt += myObj[x].name + "<br>";
  
  }
  document.getElementById("demo").innerHTML = txt;
}

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<p>A script tag with a src attribute is created and placed in the document.</p>
<p>The PHP file returns a call to a function with an object as a parameter.</p>
<p id="demo"></p>

<p>Try changing the table property from "customers" to "products".</p>

<script>
const obj = { table: "customers", limit: 10 };
let s = document.createElement("script");
s.src = "jsonp_demo_db.php?x=" + JSON.stringify(obj);
document.body.appendChild(s);

function myFunc(myObj) {
  let txt = "";
  for (let x in myObj) {
    txt += myObj[x].name + "<br>";
  }
  document.getElementById("demo").innerHTML = txt;
}
</script>

</body>
</html>

回调函数

当你无法控制服务器文件时,如何获取服务器文件 调用正确的函数?

有时服务器文件提供回调函数 一个参数:

例子

php 文件将调用您作为回调参数传递的函数:

let s = document.createElement("script");
s.src = "jsonp_demo_db.php?callback=myDisplayFunction";
document.body.appendChild(s);

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h2>Request With a Callback Function</h2>
<p>The PHP file returns a call to the function you send as a callback.</p>
<p id="demo"></p>

<script>
let s = document.createElement("script");
s.src = "demo_jsonp2.php?callback=myDisplayFunction";
document.body.appendChild(s);

function myDisplayFunction(myObj) {
  document.getElementById("demo").innerHTML = myObj.name;
}
</script>

</body>
</html>