AJAX一种创建交互式网页应用的技术,用于创建快速动态网页。
一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
在使用ajax的情况下,我们经常经常进行跨域请求
那么我们使用过程中,如何进行跨域请求呢?
我们通过jQuery的JSONP方式可以实现跨域ajax请求,服务端php也需要做出相应的处理,也就是说php这边必须和前端页面按照一定的格式请求和返回数据(json数组)。
注意:使用jsonp的时候,只有get 类型可用,即使设置了 post类型,还是使用的 get
$.ajax({
type: "get", //规定请求的类型(GET 或 POST)。
data: "random="+Math.random(), // 规定要发送到服务器的数据。
url: "https://fengkui.net/ceshi.php", //规定发送请求的 URL。默认是当前页面。
dataType: "jsonp", //预期的服务器响应的数据类型。
jsonp: "callback", //在一个 jsonp 中重写回调函数的字符串。
success: function(data) { //请求成功后返回
console.log(data);
},
error: function() { //请求失败后返回
console.log('Request Error.');
}
});
我们发现,ajax跨域请求参数中有 dataType: "jsonp" 和 jsonp: "callback" ,这个就表明了我要请求的是jsonp,并且会有回调callback返回。当然,我们也可以自定义回调函数,如 jsonpCallback:"success_jsonpCallback"
还可以简单的写成:
jQuery.getJSON("https://fengkui.net/ceshi.php?callback=?",{
random: Math.random()
}, function(data){
console.log(data);
});
php后端服务代码可以这样写(注意输出返回的格式):
$data = array(
'rand' => $_GET['random'],
'msg' => 'Success'
);
echo $_GET['callback'].'('.json_encode($data).')';
CORS是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略,浏览器会禁止这种跨域请求。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
通常在浏览器发送AJAX跨域请求时,就自动在头信息之中,添加一个Origin字段,用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
在服务端框架入口文件中加入以下代码,即接受任意域名、任意类型的请求。
// 指定允许其他域名访问
header('Access-Control-Allow-Origin: *');
// 响应类型
header('Access-Control-Allow-Methods: *');
// 响应头设置
header('Access-Control-Allow-Headers: x-requested-with, content-type');
当然我们也可以按照如下设置,限定特定的域名、特定的类型允许请求,
// 指定允许特定域名访问
header('Access-Control-Allow-Origin: https://fengkui.net');
// 响应类型
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
// 响应头设置
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept');
多个域名建议使用以下写法:
// 指定允许其他域名访问
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = array('https://fengkui.net','https://a.fengkui.net','https://b.fengkui.net');
if(in_array($origin, $allow_origin)){
header('Access-Control-Allow-Origin:'.$origin);
}
// 响应类型
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
// 否允许发送Cookie
header('Access-Control-Allow-Credentials:true');
// 响应头设置
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Apikey");
(1)Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求,多个域名用逗号分隔。
(2)Access-Control-Allow-Methods
该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。
(2)Access-Control-Allow-Headers
如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
在CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
设置完成服务的CORS之后我们就可以直接使用JSON进行请求,如下:
$.ajax({
type: "POST",
data: {'ceshi':'ceshi'},
url: "https://fengkui.net/ceshi.php",
dataType: "json",
xhrFields: {withCredentials: true}, //一对“文件名-文件值”在本机设置XHR对象。例如,用它来设置withCredentials为true的跨域请求。 用户固定PHPSESSID不变
success: function(data) {
console.log(data);
},
error: function() {
console.log('Request Error.');
}
});
总结:CORS与JSONP的使用目的相同,但是比JSONP更强大,JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
本文为冯奎原创文章,转载无需和我联系,但请注明来自冯奎博客fengkui.net
最新评论