var_dump return 一个值但 JSONP 不是

var_dump return a value but JSONP not

我有一个基于 Php Slim Framework 的 API,想为我的网站生成 JSONP。当我调用网站时:'http://api.mysite.com/users?callback=JSON_CALLBACK'。它 returns 一个空白页,上面写着 JSON CALLBACK()。当登录到控制台时,它是未定义的。

API的index.php

<?php
require 'vendor/autoload.php';

$app = new \Slim\Slim();
$app->contentType('application/json');
$app->get('/users', 'getUsers');
$app->run();

function getConnection() {
$dbhost="localhost";
$dbuser="";
$dbpass="";
$dbname="";
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

return $dbh;
}

function getUsers() {
$sql = "select * FROM manga";
try {
$db = getConnection();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo $_GET['callback'] . '('.json_encode($users).')';
}
catch(PDOException $e) {
echo $_GET['callback'] . '('.json_encode($e->getMessage()).')';
}
}

var_dump($users),调用 http://api.mysite.com/users 结果为:

function getUsers() {
$sql = "select * FROM manga";
$db = getConnection();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
var_dump($users);
}

结果:

array(2) {
[0]=>
object(stdClass)#35 (10) {
["id"]=>
string(1) "1"
["ad"]=>
string(6) "Naruto"
["yazar"]=>
string(17) "Masashi KISHIMOTO"
["icerik"]=>
string(28) "Ninja, Dövü?, Aksiyon, Drama"
["tarih"]=>
string(4) "1999"
["tur"]=>
string(5) "Manga"
["durum"]=>
string(9) "Sona Erdi"
["konu"]=>
string(560) "Yondaime Hokage, gizli bir ninja kasabas? olan Konohagakure'ye sald?ran cehennemin iblislerinden Kyuubi'yi durdurmak için, Onu yeni do?mu? bir çocuk olan Naruto'nun içine mühürler. Böylece kahram?n?m?z Naruto ortaya ç?km?? olur. ?çine mühürlenen korkunç iblis sebebiyle kasaba halk?n?n nefretini kazanan Naruto daha bebekken yetim kalm?? biridir. Kasaba halk?n?nda kendini d??lamas?ylada oldukça yaramaz ve haylaz biri çocuk olur. Fakat ninja akademisinden mezun olaca?? gün, hayat?nda ilk defa olarak arkada? edinmesi Naruto'nun hayat?n? bütünüyle de?i?tirir."
["kapak"]=>
string(10) "naruto.jpg"
["son"]=>
string(3) "300"
}
[1]=>
object(stdClass)#36 (10) {
["id"]=>
string(1) "2"
["ad"]=>
string(9) "One Piece"
["yazar"]=>
string(12) "Eiichiro ODA"
["icerik"]=>
string(32) "Macera, Komedi, Dövü?, Fantastik"
["tarih"]=>
string(4) "1997"
["tur"]=>
string(5) "Manga"
["durum"]=>
string(12) "Devam Ediyor"
["konu"]=>
string(881) "Korsan Kral Gold Roger, bu dünyadaki her?eyi elde eder ve idam edilirken, tüm servetinin Grand Line'da oldu?unu, onu aray?p bulmalar? gerekti?ini söyler. Bu olaydan sonra herkes Grand Line'a gider. Ancak Grand Line'a girmek çok zor, Grand Line'da canl? kalabilmek imkans?zd?r.

Kahraman?m?z Monkey D. Luffy'nin rüyas?, Korsan Kral olmak ve One Piece denen kimsenin bilmedi?i, görmedi?i hazineyi ele geçirmektir. Küçük ya?lardan beri hep korsan olmak isteyen Luffy, kazara bir ?eytan meyvas? (Akuma No Mi) yemi?tir. 3 farkl? ?eytan meyvas? vard?r ve bu meyvalar yiyenlere çok üstün güçler sa?lamaktad?r ancak bu güçlerin bedeli asla yüzememektir. Luffy'nin yedi?i meyva onu bir lastik çocu?a çevirir. Bu olaydan y?llar sonra Luffy denize aç?l?r. Yolculu?u s?ras?nda ekibini toplayacak ve One Piece'i bulmak için Grand Line'da birbirinden tehlikeli ve komik maceralara at?lacakt?r."
["kapak"]=>
string(13) "one_piece.jpg"
["son"]=>
string(3) "788"
}
}

您的 HTTP 响应中没有定义 javascript 函数来处理 JSONP 响应。我假设此函数然后在您的网络应用程序的另一个 JavaScript 资源(内联或脚本)中定义。因此,未定义的错误将由您在别处的 javascript 而不是此代码段引起。

要对此进行测试,请加载您的网络应用程序并启动控制台。您可以手动 运行: myCallbackFunction({field:"value"}); // 一些测试 JSON 文档 判断回调函数是否存在

但是

恕我直言 JSONP 通常是一个糟糕的想法,最好用 jQuery's page on the topic 来描述。

JSONP is essentially a consensual cross-site scripting hack

它使您的客户端应用程序更容易受到 MITM 攻击,这里是关于这个问题的SO question

由于您最终只是返回 JSON 数据而不是自定义逻辑,我建议您尝试以下操作:

  1. Return 使用 header('Content-Type: application/json); 的 JSON 编码响应。您已经非常接近使用现有代码执行此操作了。
  2. 在 JavaScript 中具有相同的回调函数,即它不需要作为 HTTP 请求的一部分传递,函数名称也不需要不同。
  3. 以与客户端几乎完全相同的方式处理 JSON。您需要对 JavaScript 进行最少的更改,因为您所做的只是将 JSON 对象按原样传递给函数。