当从同一域上的另一个页面调用时,PHP外部API访问失败?
我正在尝试使用
Jquery和
PHP / Symfony(HttpFoundation Component)进行一些小型跨站点脚本编写,但我无法让服务器返回必要的数据.
我的目标是让JQuery从本地域中检索JSON:PHP访问外部API,服务器端.我已经将Access-Control-Allow-Origin标头打开到*以允许CORS正常,并且一切都可以直接使用虚拟数据.但是,通过JQuery使用JSON端点失败.一切都发生在同一个域上. 因此,如果我手动创建JSON响应,这个虚拟JSON数据呈现正常: $data = json_decode('{ "foo": "bar","items": [ { "id": "1234","foo": "bar","baz": "bingo",},{ "id": "4567","foo": "blork","baz": "fladdurk",} }',true); $response = JsonResponse::create($data,200); $response->headers->set('Access-Control-Allow-Origin','*'); $response->send(); JSON在我的客户端显示在http:// localhost / json_endpoint?q = stuff.我找回了一个不错的JSON字符串: {"foo":"bar","items":[{"id":"1234","foo":"bar","baz":"bingo"},{"id":"4567","foo":"blork","baz":"fladdurk"}]} 这也可以在前端使用JQuery完美地运行.虚拟数据看起来完全一样,我可以使用它;可能是Symfony不介意提供JSON,而不是来自外部API. 如果我尝试向外部API(数据应该来自哪里)的PHP请求,事情开始变得奇怪: protected function url_tools__request($url,$timeout=10,$headers=array()) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_TIMEOUT,$timeout); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); //suppress output. curl_setopt($ch,CURLOPT_HTTPHEADER,$headers); $ch_exec = curl_exec($ch); curl_close($ch); return $ch_exec; } $url = "http://api.example.com/?q=more+stuff"; $headers = array("Accept:application/json"); $xsr = $this->url_tools__request($url,10,$headers); $data = [ "foo" => "bar",// here's the rub "items" => json_decode($xsr,true),]; $response = JsonResponse::create($data,'*'); $response->send(); 使用此实时数据,如果直接在http:// localhost / json_endpoint?q = stuff访问,则所有内容都在客户端中正确显示.所以API工作正常.我得到与上面完全相同的完整JSON字符串: {"foo":"bar","baz":"fladdurk"}]} 但是,如果我尝试通过JQuery AJAX(可能在http://localhost/another_page.html)访问此端点,我会返回一个没有任何“items”的JSON字符串: {"foo":"bar","items":[]} 我的JQuery代码如下所示: xhr = $.ajax({ url: '/json_endpoint',data: {q: "more+stuff"},type: "GET",dataType : "json" }) .done(function(data,textStatus,request) { console.log(data) } 我从各个角度查看了我的请求和响应,无论是使用虚拟或实际(XSS)数据,PHP / Symfony解析的字符串都是相同的.我很确定没有竞争条件或任何事情. 知道我做错了什么吗?提前致谢. 解决方法
原来CORS的东西完全是红鲱鱼.
JQuery使用百分号对URL进行编码,这是我的PHP没有考虑的问题.我将失败的调用解释为CORS的错误;此情况并非如此. 所以这个网址实际上会起作用: $url = "http://api.example.com/?q=stuff"; 问题在于更复杂的URL,空格和标点符号.直接访问时,这可以正常工作: $url = "http://api.example.com/?q=more+stuff"; 但是在使用JQuery时,它决定将查询字符串转换为: more%sBstuff ……令人困惑的是PHP.在我的代码中更高,我之前有这个: $url = urlencode($request->get('q')); 现在我不得不添加另一个urldecode $query = urlencode(urldecode($request->get('q'))); 对此感到抱歉.我希望有一天能在互联网上帮助某人. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |