curl实现跨域请求数据

杂散   874阅读

遇到一个有趣的链接,在浏览器里访问这个链接会返回一串json格式的数据,理论上,可以在网页里面通过ajax之类的方法来自动获取到这个json的数据,于是就把脚本开始写起来。
一个简单的脚本写出来差不多是这个样子。这个url是真实的地址,来自阿里指数。

<script> 
$.ajax({ 
    type:"GET", 
    url:"https://alizs.taobao.com/searchKeyword/getRank.json?cateId="+sdata[i]+"&dateType=recent7&dateRange=2016-07-22|2016-07-28&type=hot&dtMaxAge=86400000&ctoken=TRH4wiVWobaSkRAubHq1alizs&_=1469802272454", 
    data:'', 
    dataType:"json",     
    success:function(data){ 
        alert(data); 
    } 
}); 
</script>

这个脚本在运行之后没有弹出警告框,也就是没有GET到数据,通过浏览器的开发者模式,很直观的可以发现我们的测试域的地址不在可以调用的的允许范围之内,由于这个路径是阿里的,我们不能修改对方的Access-Control-Allow-Origin,所以挣扎半天还是突破不了。
 
后来在网上看到说吧dataType的值修改成jsonp就可以了,但是我这样测试发现返回的提示是MIME类型不对,因为jsonp要求返回的是一个javascript的文件,而我们这个链接返回的是json,同样是不能修改对方的文件,所以放弃了这种办法。
 
然后又想试一下通过iframe来引用这个链接,然后通过获取iframe的页面内容来获取数据,但是对方设置了x-frame-options:SAMEORIGIN,这样也就不能被嵌入到别人网页的iframe里。
 
上面的三种尝试总结起来,都是希望通过javascript的脚本来控制网页的内容,但是由于对方的程序在开发的时候进入了全方位的限制,使得javascript获取不到任何的控制权限。
 
前端的权限不够,我只要转而向后端寻求办法,基本的思路类似于采集远程网页,另外这个链接是需要登录验证的。
curl是一个很强大的组件,可以模拟一个真实的浏览网页的行为

<?php 
$ch = curl_init(); 
curl_setopt($ch,CURLOPT_URL,'https://alizs.taobao.com/searchKeyword/getRank.json?cateId='.$value[2].'&dateType=recent7&dateRange=2016-07-22%7C2016-07-28&type=hot&dtMaxAge=86400000&ctoken=TRH4wiVWobaSkRAubHq1alizs&_=1469802272454');   
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch,CURLOPT_COOKIE,'you cookie');   
$output = curl_exec($ch); 
curl_close($ch); 
$output_array = json_decode($output,TRUE); 
?>

其中,
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
可以绕过HTTPS的安全验证。
而curl_setopt($ch,CURLOPT_COOKIE,'you cookie');  这可以提交一段cookie,模拟登陆。
cookie可以通过浏览器的开发者模式获取。
 
所以,经过反复的摸索之后,通过curl来实现跨域请求数据。目前我通过这种方法一共获取了19.3MB的数据,在获取数据的过程中,出现了php内存错误,这跟我没有优化程序有关系,随着程序的运行,缓存占用了大量的内存空间。

尽管如此,我还是要提出一个思考了比较长时间的一个问题。在做开发的时候,尽量发挥客户端的计算机资源,把需要在服务器上集中处理的任务通过合理的设计分散到各个客户端上去。

以我这次的跨域获取数据的例子来说,原本我是想通过前端页面的javascript脚本来获取远程的json数据,这样对我的web服务器几乎没有压力,而当通过curl来实现跨域获取数据之后,所有的压力就加在了服务器上,所以当同时并发需要处理大量的数据时,这时候就开始考验服务器的性能了。

喜欢请常来,打赏请随意。

  1. 无声有处    回复

    哈哈 技术很牛的样子。
  2. 故事会    回复

    哎,挺复杂的、、、、