当从同一域上的另一个页面调用时,PHP外部API访问失败?

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了当从同一域上的另一个页面调用时,PHP外部API访问失败?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用 JqueryPHP / 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')));

对此感到抱歉.我希望有一天能在互联网上帮助某人.

脚本宝典总结

以上是脚本宝典为你收集整理的当从同一域上的另一个页面调用时,PHP外部API访问失败?全部内容,希望文章能够帮你解决当从同一域上的另一个页面调用时,PHP外部API访问失败?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。