在web开发中,跨域是一个经常碰到的情况。结合开发中碰到的实际情况,自己总结了一些跨域的相关方法整理如下。关于跨域的原理请大家自行google或baidu相关的资料。
假设有一个需求为输入姓名和年龄去查询航班信息(纯粹是为了演示跨域)前端请求的页面为:http://www.c.com/c.php 。 服务端的处理程序为:http://www.s.com/s.php
- jsonp的跨域方法如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jquery跨域测试</title>
<script src="/jquery-1.8.3.min.js"></script>
</head>
<body>
<form name="form">
姓名:<input id="name" type="text" name="name">
年龄:<input id="age" type="text" name="age">
<input type="button" id="btn" value="button" />
</form>
<script type="text/javascript">
//ajax jsonp 方法
$("#btn").click(function (k) {
var j = $("form").serializeArray();//序列化name/value
$.ajax({
type: "GET",
async: false,
url: "http://www.s.com/s.php",
data: j,
dataType: "jsonp",
jsonp: "callback", //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
//jsonpCallback: "test", //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function (json) {
alert('姓名:' + json.name + ', 年龄:' + json.age + ', 您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。回调函数名为: ' + json.func);
},
error: function () {
alert("fail");
}
});
//...
});
</script>
</body>
</html>
服务端的处理:
<?php
$callback = $_GET["callback"];
$a = array(
'code' => 'CA1998',
'price' => '6000',
'tickets' => 20,
'msg' => 'ok',
'name' => $_GET['name'],
'age' => $_GET['age'],
'func' => $callback,
);
$result = json_encode($a);
echo "$callback($result)";
exit;
- jquery $.getJSON跨域请求方法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jquery跨域测试</title>
<script src="/jquery-1.8.3.min.js"></script>
</head>
<body>
<form name="form">
姓名:<input id="name" type="text" name="name">
年龄:<input id="age" type="text" name="age">
<input type="button" id="btn" value="button" />
</form>
<script type="text/javascript">
$(function(){
$("#btn").click(function (k) {
var name = $('#name').val();
var age = $('#age').val();
$.getJSON(
"http://www.s.com/s.php?&name="+name+"&age="+age+"&callback=?",
function (json) {
alert('姓名:' + json.name + ', 年龄:' + json.age + ', 您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。回调函数名为: ' + json.func);
}
);
});
});
</script>
</body>
</html>
服务端处理代码:
<?php
$callback = $_GET["callback"];
$a = array(
'code' => 'CA1998',
'price' => '6000',
'tickets' => 20,
'msg' => 'ok',
'name' => $_GET['name'],
'age' => $_GET['age'],
'func' => $callback,
);
$result = json_encode($a);
echo "$callback($result)";
exit;
- cors跨域方法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jquery跨域测试</title>
<script src="/jquery-1.8.3.min.js"></script>
</head>
<body>
<form name="form">
姓名:<input id="name" type="text" name="name">
年龄:<input id="age" type="text" name="age">
<input type="button" id="btn" value="button" />
</form>
<script type="text/javascript">
//cors 跨域
$("#btn").click(function (k) {
var name = $('#name').val();
var age = $('#age').val();
var d_post = {'name':name,'age':age};
$.ajax({
url: 'http://www.s.com/s.php',
data: d_post,
type: "POST",
dataType: "json",
success: function (json) {
console.log(json);
alert('姓名:' + json.name + ', 年龄:' + json.age + ', 您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张');
},
error: function (data) {
//alert("fail");
console.log(data);
}
});
});
</script>
</body>
</html>
服务端处理代码:
<?php
//cors服务度
$w_url = array('http://www.c.com','http://www.c2.com'); //设置允许跨域访问的白名单信息,如果有多个白名单,可以都加入到白名单数组中
$origin = $_SERVER['HTTP_ORIGIN']; //获取当前跨域请求的域名
if (!empty($origin) && in_array($origin, $w_url)) {
//设置 header 信息
header("Access-Control-Allow-Headers", "accept, content-type");
header("Access-Control-Allow-Origin:".$origin); //设置允许访问的域名
header("Access-Control-Allow-Methods", "POST,GET"); //允许的访问方式
header('Access-Control-Allow-Credentials:true'); //允许访问Cookie
header('Access-Control-Allow-Headers : X-Requested-With'); //设置Headers
$a = array(
'code' => 'CA1998',
'price' => '6000',
'tickets' => 20,
'msg' => 'ok',
'name' => $_POST['name'],
'age' => $_POST['age']
);
echo json_encode($a);
exit();
} else {
//非白名单的跨域请求直接返回一个空信息
echo json_encode(array('啥也没有'));
exit();
}
- 代理(proxy)方法跨域:
web端 www.c.com/c.php 先请求 同域的服务端如:www.c.com/s.php,
然后s.php 再请求www.s.com/s.php。相当于www.c.com/s.php去请求了一个接口:www.s.com/s.php