序
平时工作中用到ajax比较多,一般都是直接用jquery里的ajax来操作的,说实话jquery真的很好用,给我工作带来的很大的便利,但我们要学会知其然知其所以然,所以我决定自己封装一个ajax方法,现在分享给大家,希望对大家有帮助。关于ajax简介及基础建议大家可以去w3school
看上边的文档。
js文件ajax.js
/**
* 解决跨域问题
* header('Access-Control-Allow-Origin:*');
* JOSNP:<?PHP echo $_GET['callback'].'({"name":"kwin"})';
*
* [ajax description]
* @param object obj
{
type:"post|get",
url:"http://example.com",
async:"true",
dataType:"HTML|text|XML|JSON|JSONP",
data:{},
beforeSend:function(xmlhttp){},
success:functuon(data){},
error:function(err){}
}
* @return {[type]} [description]
*/
function ajax(obj) {
var xmlhttp, type, url, async, dataType, data;
if (typeof(obj) != 'object') return false;
type = obj.type == undefined ? 'POST' : obj.type.toUpperCase();
url = obj.url == undefined ? window.location.href : obj.url;
async = obj.async == undefined ? true : obj.type;
dataType = obj.dataType == undefined ? 'HTML' : obj.dataType.toUpperCase();
data = obj.data == undefined ? {} : obj.data;
var formatParams = function () {
if (typeof(data) == "object") {
var str = "";
for (var pro in data) {
str += pro + "=" + data[pro] + "&";
}
data = str.substr(0, str.length - 1);
}
if (type == 'GET' || dataType == 'JSONP') {
if (url.lastIndexOf('?') == -1) {
url += '?' + data;
} else {
url += '&' + data;
}
}
}
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if (dataType == 'JSONP') {
if (typeof(obj.beforeSend) == 'function')obj.beforeSend(xmlhttp);
var callbackName = ('jsonp_' + Math.random()).replace(".", "");
var oHead = document.getElementsByTagName('head')[0];
data.callback = callbackName;
var ele = document.createElement('script');
ele.type = "text/javascript";
ele.onerror = function () {
console.log('请求失败');
obj.error && obj.error("请求失败");
};
oHead.appendChild(ele);
window[callbackName] = function (json) {
oHead.removeChild(ele);
window[callbackName] = null;
obj.success && obj.success(json);
};
formatParams();
ele.src = url;
return ;
} else {
formatParams();
xmlhttp.open(type, url, async);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
if (typeof(obj.beforeSend) == 'function')obj.beforeSend(xmlhttp);
xmlhttp.send(data);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.status != 200) {
console.log(xmlhttp.status + '错误');
obj.error && obj.error(xmlhttp.status + '错误');
return ;
}
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (dataType == 'JSON') {
try {
res = JSON.parse(xmlhttp.responseText);
} catch (e) {
console.log('返回的json格式不正确');
obj.error('返回的json格式不正确');
}
} else if (dataType == 'XML') {
res = xmlhttp.responseXML;
} else {
res = xmlhttp.responseText;
}
obj.success && obj.success(res);
}
}
}
}
html文件 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX TEST</title>
<script charset="utf-8" src="ajax.js"></script>
<script>
function ajaxTest() {
ajax({
type: 'get',
url: "http://localhost/ajax.php",
async: true,
dataType: 'JSONP',
data: {
fname: 'Henry'
},
beforeSend:function(xmlhttp){
xmlhttp.setRequestHeader("test", "application/x-www-form-urlencoded");
console.log(xmlhttp);
},
success: function(json) {
alert(JSON.stringify(json));
},
});
}();
</script>
</head>
<body>
</body>
</html>
关于跨域问题
同源策略
由于浏览器遵守着同源策略
这一约定,阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的URL的域必须与当前Web页面同一域名
、同一端口
和同一协议
。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。
解决方法
在请求的文件中增加头文件
<?php
header('Content-type: application/json');
header('Access-Control-Allow-Origin:*');
echo '{"name":"kwinwong"}';
Access-Control-Allow-Origin:* 如果它的值设为 * ,则表示谁都可以用:一般情况下我们会按需求设置域名 如:header(‘Access-Control-Allow-Origin:http://example.com‘);
JSONP
JSONP(JSON with Padding) 是一种跨域请求方式。由于浏览器允许跨源请求script资源,主要原理是利用了script 标签可以跨域请求的特点,由其 src 属性发送请求到服务器,服务器返回 js 代码,网页端接受响应,然后就直接执行了,这和通过 script 标签引用外部文件的原理是一样的。
jsonp.php
<?php
echo $_GET['callback'].'({"name":"kwin"})';
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP TEST</title>
</head>
<body>
<script type="text/javascript">
function jsonp_3532(json) {
alert(JSON.stringify(json));
}
</script>
<script charset="utf-8" src="http://127.0.0.2/jsonp.php?callback=jsonp_3532"></script>
</body>
</html>
我们将jsonp.php当作js加载,并告诉服务器让它调用jsonp_3532这个方法,由此我们应该基本了解了JSONP的原理及基本的使用方法了,由于JSONP是通过src调用的,所以只能用GET方式,如果数据比较大或则要用到POST方式时,那只能使用修改头文件的方法了