Ajax 跨域请求的解决方案
原创
©著作权归作者所有:来自51CTO博客作者郎涯工作室的原创作品,请联系作者获取转载授权,否则将追究法律责任
Ajax技术的核心是XMLHttpRequest对象(简称XHR),可以通过使用XHR对象获取到服务器的数据,然后再通过DOM将数据插入到页面中呈现。虽然名字中包含XML,但Ajax通讯与数据格式无关,所以我们的数据格式可以是XML或JSON等格式。
XMLHttpRequest对象用于在后台与服务器交换数据,具体作用如下:
- 在不重新加载页面的情况下更新网页
- 在页面已加载后从服务器请求数据
- 在页面已加载后从服务器接收数据
- 在后台向服务器发送数据
XMLHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
跨域请求数据解决方案主要有如下解决方法:
- JSONP方式
- 表单POST方式
- 服务器代理
- Html5的XDomainRequest
- Flash request
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过Javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。原理不多介绍,接下来是示例。
【1】php定义的API接口
API的地址为:http://192.168.1.102:8002/regular.php
<?php
//jsonp ajax跨域请求!!!
$g_callback = null;
if(isset($_REQUEST['jsonp_callback']))
{
$g_callback = $_REQUEST['jsonp_callback'];
}
if (isset($_REQUEST['name'])) {
echo jsonencode(
array(
'code' => 200,
'msg' => '调用成功',
'result' => array(
'name' => $_REQUEST['name']
)
),
$g_callback
);
exit;
} else {
echo jsonencode(
array(
'code' => 400,
'msg' => '调用失败',
'result' => array(
'name' => ''
)
),
$g_callback
);
exit;
}
function jsonencode($datas, $callback=null)
{
$jsonp = null;
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
$jsonp = json_encode($datas, JSON_HEX_TAG | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_HEX_APOS);
}
else
{
$jsonp = json_encode($datas);
}
if(!is_null($callback))
return $callback . '(' . $jsonp . ')';
return $jsonp;
}
【2】调用API的JS文件
JS的地址为:http://192.168.1.102:8001/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="jquery-1.12.2.min.js"></script>
<title>ajax 跨域调用</title>
</head>
<body>
<script type="text/javascript">
$(function(){
$.ajax(
{
type: 'get',
async : false,
cache : false,
dataType : 'jsonp',
url : 'http://192.168.1.102:8002/regular.php',
data: {
"name": 'iloveyou',
"pass": 'hacfin_token'
},
jsonp:"jsonp_callback",
success : function(data) {
alert("code:"+ data.code +" msg:"+ data.msg);
},
error : function() {
alert('fail');
}
}
);
})
</script>
</body>
</html>
【3】执行结果
注意:
JSONP works by creating a <script> tag that executes Javascript from a different domain;it is not possible to send a POST request using a <script> tag. 表示jsonp不支持POST请求。
http://stackoverflow.com/questions/3860111/how-to-make-a-jsonp-post-request-that-specifies-contenttype-with-jquery
如果想支持POST请求,可以跨域资源共享。cors有些老浏览器不支持(IE8以上),但是get/post都支持。需要服务器协助设置相关参数,http://caniuse.com/#search=cors
客户端更改:
添加:crossDomain: true
修改:dataType: "json"
服务端添加:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Headers: Content-Type,X-Requested-With,X_Requested_With');