Ajax 基础知识
代码一把梭,快来人教我做菜吧
Ajax
ajax
直接看一个老版本例子
var xmlHttp = null
// 老版本的 IE5 和 IE6 使用 ActiveX 对象
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveObject('Microsoft.XMLHTTP');
}
/*
一个请求过程
xmlHttp
responseType //设定数据返回类型
open(module,url,async) //module == get && post url == 链接 saync==true && false 是否异步
setRequestHeader() // 设定发送请求的头部
send() //发送请求
*/
xmlHttp.responseType = 'JSON';
xmlHttp.open('GET', 'https://www.apiopen.top/satinApi', 'true');
xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHttp.send();
/*
onreadystatechange:只要 readyState 属性发生变化,就会调用相应的处理函数,一般用于获取返回的数据
*/
xmlHttp.onreadystatechange = function () {
if(xmlHttp.readyState === XMLHttpRequest.DONE && xmlHttp.status === 200) {
console.log(xmlHttp.responseText)
}
}
解读步骤
使用 ajax
发送链接,不外乎几个步骤;
- 创建
XMLHttpRequest
对象; - 配置发送请求的模式
get
orpost
,以及请求链接,是否异步,返回数据格式 - 使用
XMLHttpRequest
对象open()
方法,根据配置发送请求 - 使用
XMLHttpRequest
对象responseType
属性,设定返回数据类型 - 根据
XMLHttpRequest
对象onreadystatechange
事件监听readyState
属性变化,获取responseText
返回数据;
注意事项
- 当设定为同步请求的时候,请求会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止,这时候就不需要使用
onreadystatechange
函数 ,直接获取responseText
即可 - 当设定为
post
请求的时候,send()
可以传入参数,例:
//...
xmlHttp.responseType = dataType;
xmlHttp.open('POST', url, aysnc);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send(parems);
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
callback(xmlHttp.response);
}
}
Jsonp
简单实现
function jsonp(req){
var script = document.createElement('script');
var url = req.url + '?callback=' + req.callback.name;
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
原理解读
利用 <script>
标签的 src
属性来实现 get
请求;
为什么会有 Jsonp
同源策略 大概了解一下?
- 协议,端口(如果有指定)和域名都相同,则具有相同的源,页面可以直接通过请求,获得数据;
- 突破协议请求,即是说所的跨域;
- 通过
jsonp
技巧获取的数据已经不是json
,而是JS
类型的数据(大部分是对象),所以jsonp
只有get
请求,没有post
;
jsonp的最优方案
(function (global) {
var id = 0,
container = document.getElementsByTagName("head")[0];
function jsonp(options) {
if(!options || !options.url) return;
var scriptNode = document.createElement("script"),
data = options.data || {},
url = options.url,
callback = options.callback,
fnName = "jsonp" + id++;
// 添加回调函数
data["callback"] = fnName;
// 拼接url
var params = [];
for (var key in data) {
params.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
url = url.indexOf("?") > 0 ? (url + "&") : (url + "?");
url += params.join("&");
scriptNode.src = url;
// 传递的是一个匿名的回调函数,要执行的话,暴露为一个全局方法
global[fnName] = function (ret) {
callback && callback(ret);
container.removeChild(scriptNode);
delete global[fnName];
}
// 出错处理
scriptNode.onerror = function () {
callback && callback({error:"error"});
container.removeChild(scriptNode);
global[fnName] && delete global[fnName];
}
scriptNode.type = "text/javascript";
container.appendChild(scriptNode)
}
global.jsonp = jsonp;
})(this);
/*
使用示例
*/
jsonp({
url : "www.example.com",
data : {id : 1},
callback : function (res) {
console.log(res);
}
});
目前所知发起请求的方式
- 用
form
标签发起get
和post
请求,会刷新页面或跳转页面; - 用
a
标签只能发起get
请求,会刷新当前页面或跳转页面; - 用
link
标签只能发起get
请求,无法访问服务器的响应文本,只能以CSS
、favicon
的形式展示; - 用
img
标签只能发起get
请求,跨域请求技术的一种,无法访问服务器的响应文本,只能以图片的形式展示,只能用于浏览器与服务器间的单向通信; - 用
script
标签只能发起get
请求,只能以脚本的形式执行(jsonp的原理); - 使用
Ajax
发送异步或者同步请求;
总结
本文上面的方法都是很直白的,没有任何封装成分,之所以直接上代码,是因为不太想啰嗦了,不懂得欢迎前来质询;
这里有封装过的装逼代码,但是没有用到设计模式成分,所以依然是很 low 哒,欢迎指出错误并讨论更优方案;
感谢校长的文章启发;
感谢阅读;