今天遇到个问题,ajax无法跨域访问,找了好多方法,类似jsonp,CORS(跨域资源共享),josnp的弊端在于只适用get请求,CORS确实比jsonp更快速便捷但是总感觉不舒服,
后来想着能不能用服务端对话服务端不用前端js写,尝试着用了一下之前集成环信时候核心类里边的postCurl方法访问跨域的接口地址,结果是成功返回了数据,然后通过
控制器里边的一个方法转发一下,前端js访问本项目的控制器方法就不存在跨域问题了,这个方法是不是最好不说但是确实是用PHP解决了跨域问题。
1.环信核心包在上上篇博客有下载地址,这里我就只贴postCurl方法好了
/**
*$this->postCurl方法
*/
function postCurl($url,$body,$header,$type="POST"){
//1.创建一个curl资源
$ch = curl_init();
//2.设置URL和相应的选项
curl_setopt($ch,CURLOPT_URL,$url);//设置url
//1)设置请求头
//array_push($header, 'Accept:application/json');
//array_push($header,'Content-Type:application/json');
//array_push($header, 'http:multipart/form-data');
//设置为false,只会获得响应的正文(true的话会连响应头一并获取到)
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt ( $ch, CURLOPT_TIMEOUT,5); // 设置超时限制防止死循环
//设置发起连接前的等待时间,如果设置为0,则无限等待。
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5);
//将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//2)设备请求体
if (count($body)>0) {
//$b=json_encode($body,true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);//全部数据使用HTTP协议中的"POST"操作来发送。
}
//设置请求头
if(count($header)>0){
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
}
//上传文件相关设置
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);// 从证书中检查SSL加密算
//3)设置提交方式
switch($type){
case "GET":
curl_setopt($ch,CURLOPT_HTTPGET,true);
break;
case "POST":
curl_setopt($ch,CURLOPT_POST,true);
break;
case "PUT"://使用一个自定义的请求信息来代替"GET"或"HEAD"作为HTTP请 求。这对于执行"DELETE" 或者其他更隐蔽的HTT
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"PUT");
break;
case "DELETE":
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"DELETE");
break;
}
//4)在HTTP请求中包含一个"User-Agent: "头的字符串。-----必设
curl_setopt($ch, CURLOPT_USERAGENT, 'SSTS Browser/1.0');
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
curl_setopt ( $ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)' ); // 模拟用户使用的浏览器
//5)
//3.抓取URL并把它传递给浏览器
$res=curl_exec($ch);
$result=json_decode($res,true);
//4.关闭curl资源,并且释放系统资源
curl_close($ch);
if(empty($result))
return $res;
else
return $result;
}
2.我的控制器转发方法
<?php
namespace Admin\Controller;
use Think\Controller;
use Think\Easemob;
class IndexController extends Controller {
public function index(){
$url = "http://v.juhe.cn/toutiao/index?type=top&key=b1c132fbf66fd064538623f99944ac2b";
$ea = new Easemob();
$result = $ea->postCurl($url);
/*$this->assign("result",$result['result']['data']);
$this->display("index");*/
$this->ajaxReturn($result);
}
}
3.页面的ajax方法输出访问到的新闻标题
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="__PUBLIC__/static/jquery-2.0.3.min.js"></script>
<link href="//cdn.bootcss.com/amazeui/2.7.2/css/amazeui.min.css" rel="stylesheet">
<script>
$(function(){
$.ajax({
type:"get",
url:"{:U('Index/index')}",
success:function(data){
var news = data['result']['data'];
for(var i=0;i<news.length;i++){
$("#mylist").append("<li><a href=''>"+news[i]['title']+"</a></li>");
}
}
});
});
</script>
</head>
<body>
<ul id="mylist" class="am-list">
<li><a href="javascript:void(0)">PHP转发解决ajax跨域问题</a></li>
</ul>
</body>
</html>