【发布时间】:2014-04-07 22:04:00
【问题描述】:
我相信以前有人问过这个问题,但给出的答案不足以说明我的代码哪里出错了。如果存在类似的问题,我深表歉意;我花了几个小时搜索,但找不到解决方案。
我用 PHP 构建了一个小型 RESTful 式服务,将数据库信息引入我的站点。我能够成功地从浏览器和 Fiddler 进行调用,但是当我尝试从 $.ajax() 请求数据时,我崩溃了。首先,让我发布PHP代码:
我打电话给http://api.horodyski.me
class ApiController
{
protected $endpoint = '';
protected $method = '';
protected $verb = '';
protected $args = Array();
public function __construct($request)
{
header("Access-Control-Allow-Orgin: *");
header("Access-Control-Allow-Methods: GET");
header("Content-Type: application/json");
$this->args = explode('/', rtrim($request, '/'));
$this->endpoint = array_shift($this->args);
if (array_key_exists(0, $this->args) && !is_numeric($this->args[0])) { $this->verb = array_shift($this->args); }
$this->method = $_SERVER['REQUEST_METHOD'];
if($this->method != 'GET')
throw new Exception("Unexpected Header");
$this->request = $this->_cleanInputs($_GET);
}
public function processAPI()
{
$class = $this->endpoint."Controller";
if(class_exists($class))
{
$controller = new $class();
return $this->_response($controller->getAllItems());
}
return $this->_response("No Endpoint: ".$this->endpoint, 404);
}
private function _response($data, $status = 200)
{
header("HTTP/1.1 ".$status." ".$this->_requestStatus($status));
// $data comes back from controller in JSON format.
return json_encode($data);
}
private function _cleanInputs($data)
{
$cleanInput = Array();
if(is_array($data))
foreach($data as $k => $v)
$cleanInput[$k] = $this->_cleanInputs($v);
else
$cleanInput = trim(strip_tags($data));
return $cleanInput;
}
private function _requestStatus($code)
{
$status = array(
200 => 'OK',
404 => 'Not Found',
405 => 'Method Not Allowed',
500 => 'Internal Server Error',
);
return ($status[$code]) ? $status[$code] : $status[500];
}
}
我已经尝试实现返回 jsonp 的 jQuery 调用,这就是我卡住的地方。
请求来自http://horodyski.me/v2。下面的代码显示了正常的json 返回类型:
<p class="test"></p>
<script>
$(document).ready(function () {
$.ajax({
url: "http://api.horodyski.me/skills",
method: "GET",
dataType: 'jsonp',
success: function (data) {
$("p.test").text(data);
},
error: function (xhr, textStatus, error) {
debugger;
}
});
});
</script>
我在错误回调中得到以下信息:
textStatus = "parseerror"
error = "jQuery210008879405278902885_1396911952892 was not called"
同样,Fiddler 没有显示错误——我没有想法。我在 PHP 端没有正确处理它,还是我的 jQuery 搞砸了?也许我需要编辑我的.htaccess 文件来处理 jQuery 在 jsonp 调用上发送的回调参数?我有点不知所措,有什么建议吗?
我可以打电话给http://horodyski.me/api/skills,它可以使用常规 json,但我仍然无法让 CORS 正常工作。
【问题讨论】:
-
要使用
JSONP,您的API 需要能够处理它:使用JSONP,API 必须返回一个以JSON数据作为参数的方法调用。要调用的方法名称通常可以用jsonp之类的参数指定(实现由您决定)。一个例子是 SO API:api.*.com/1.1/tags/ravendb/wikis?jsonp=useData(useData是这里的回调方法名称) -
注意:JSONP 和 CORS 是不同的方法。要了解 JSONP 因缺少回调函数而失败的原因,请参阅上面的链接。但是发布的代码还有另一个问题,因为服务器端是为 CORS 设置的,而客户端使用的是 JSONP。选择一个并在两侧实施。我认为在服务器上设置 CORS 后,将客户端更改为使用 CORS 是最简单的。
-
问题是浏览器/jQuery 端而不是服务器端。下面是针对 CORS 的 jQuery AJAX 请求:html5rocks.com/en/tutorials/cors/#toc-cors-from-jquery
-
这是一个进步。至少连接的双方都在尝试做同样的事情......
-
对于
Access-Control-Allow-Origin尝试发回原始* URL(http://somewhere.com- 存储 javascript 文件的主机名)而不是“*”。
标签: javascript php jquery ajax json