Ajax基础
当前端需要向后端请求数据的时候,我们有很多种方式 ,如表提交,websocket。今天我们再学习一种ajax
Ajax是一种异步数据通讯方法,它是由前端向服务器发送请求,服务器再返回一个响应给我
在window浏览器对象下面,有一个属性对象叫 XMLHttpRequest
,它就是我们的ajax核心 ,它简称xhr
Ajax的初始化
Ajax的核心对象是XMLHttpRequest
,但是这个对象有兼容性,所以我们要做兼容处理
var xhr = null;
if (window.XMLHttpRequest) {
//说明是新版本的浏览器,或是以谷歌(webkit)为核心的浏览器
//新版本的IE也具备这个属性了
xhr = new XMLHttpRequest();
} else {
//老版本的IE
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
后面可以直接简写成下面的方式
var xhr=Window.XMLHttpRequest?new XMLHttpRequest():new ActivexObject("Microsoft.XMLHTTP")
建立请求过程
在监听Ajax状态变化之前,我们要建议请求
xhr.open(请求方式,请求url,异步/同步);
- 请求方式常见的有"GET"和"POST"
- 同步则是false,异步是true
同步会等待,异步会执行
xhr.open("get","http://www.xxx.com",true); //发起一个异步请求
Ajax的请求状态变化
Ajax的请求状态有5个步骤
- 请求未初始化
- 服务器连接已建立
- 请求已接收
- 请求处理中
- 请求已完成,且响应已就绪
只请当请求的状态为4的时候,才说明请求已完成。在判断请求完成的时候,我们还要判断请求状态的状态码
- 500开头的服务器
- 200代表功能
- 404代表请求路径错误 ,找不到请求地址
- 403没有请求权限
- 304缓存
xhr.onreadystatechange = function () {
// 请求状态为4并且状态码为200,则代表请求成功
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(typeof xhr.responseText);
//接口返回的是一个json字符串,那么,我们就可以通过JSON.parse去做一次转换,在jQuery里面它会自己做转换
var obj=JSON.parse(xhr.responseText);
console.log(obj);
}
}
在DOM里面,事件的英文单词全小写
Ajax发送数据
xhr.send(参数);
当是post请求的时候,参数应该在send方法里面,当请求方式是get的时候,请求参数直接接在了请求地址的后面
Ajax注意事项
ajax的请求方式有两种,一种是get,一种是post。在不同的请求方式里面,它的配置是不一样的
关于get请求
get请求的注意事项如下
直接在浏览器里面输入地址,它也是一个get请求
-
它的请求参数直接拼在了请求地址的后面
var url="https://www.softeem.xin/maoyanApi/ajax/detailmovie"; //这是请求地址 var params="movieId=1277982"; //请求参数 xhr.open("get",url+"?"+params,true);
-
因为get请求本质上面是通过浏览器的地址在拼接请求参数,所以它有大小限制,它不能够提交大量的数据到后台
同时它还不能提交文件到后台,所以get请求只适合处于少量的文本数据参数
get请求的参数会暴露在浏览器地址栏,这个时候,如果有敏感信息就会非常麻烦。所以它的安全性不高
关于post请求
post请求与get请求不一样,它主要的区别与注意事项如下
-
post请求的时候,它的参数没有拼在URL地址后面,所以后期如果通过Ajax进行请求的时候,它需要在主动发送请求参数
xhr.send(params);
-
post请求要根据请求参数设置请求的header【请求头】
var params="s_id=20190101&s_tel=18627104906"; //这是请求参数 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.send(params);
如果请求参数是一个对象的时候,则请求头又需要进行改变
var params={ s_id:"20190101", s_tel:"18627104906" } xhr.setRequestHeader("Content-Type","application/json"); xhr.send(JSON.stringify(params));
-
post请求与get主求相反,它可以提交大量的数据,只要后台不做限制【如果后台服务器做了限制,就以后台服务器为主】
get只能提交少量的文本参数,但是post不仅可以提交大量的文本参数,还可以提交非文本类型的参数,例如文件(这个时候,它就不是文本参数,它是以流的形式提交的);
Ajax的封装
ajax是前端最常用的一个技术 ,前端可以借用于第三方框架(如 jQuery)去使用ajax,但是我们仍然需要掌握自己封装的技巧
第一个版本的封装
该版本是一个方法的版本,需要严格的对参数进行控制
function ajaxHelper(method,url,callBack,params){
var xhr=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
xhr.open(method,url,true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
if(typeof callBack=="function"){
//调用这个回调方法,并且向这个回调方法里面传递一个实参
callBack(xhr.responseText);
}
}
}
if(method.toUpperCase()=="GET"){
xhr.send();
}
else if(method.toUpperCase()=="POST"){
//首先判断params有没有值
if(params){
if(typeof params=="string"){
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(params)
}
else if(typeof params=="object"){
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(JSON.stringify(params));
}
}
else{
xhr.send();
}
}
}
现在我们对上面的版本进行测试
get测试
var url="https://www.softeem.xin/maoyanApi/ajax/detailmovie"; //这是请求地址
var params="movieId=1277982"; //请求参数
ajaxHelper("get",url+"?"+params,function(data){
console.log(data);
});
测试结果正常
post测试
var url="http://www.softeem.xin:8086/StuInfo/checkLogin";
var params="s_id=20190101&s_tel=18627104906";
ajaxHelper("post",url,function(data){
console.log(data);
},{
s_id:"20190101",
s_tel:"18627104906"
});
在这个POST里面,我们分别对参数做了两次处理,一次是params
的字符串,一次是对象,这两次都正常
在上面的封装里面,它是一个方法的封装,但是我们希望能够像jQuery
里面一样进行get
和post
的请求,这个时候,我们可以像如下方式去封装
第二个版本
!function () {
Object.defineProperty(window, "ajaxHelper", {
configurable: false,
enumerable: true,
writable: false,
// 使用了冻结对象
value:Object.freeze({
//初始化
init: function (method, url, callBack) {
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (typeof callBack == "function") {
callBack(xhr.responseText);
}
}
}
return xhr;
},
//假设它的请求地址与请求参数是接在一起,拼成了URL
get: function () {
var url, params, callBack;
if (arguments.length == 2) {
url = arguments[0];
callBack = arguments[1];
} else if (arguments.length == 3) {
url = arguments[0];
params = arguments[1];
callBack = arguments[2];
if (typeof params == "string") {
url = url + "?" + params;
} else if (typeof params == "object") {
var str = "";
for (var i in params) {
if (params[i] instanceof Array) {
//是数组,再去遍历一次
for (var j in params[i]) {
str += i + "=" + params[i][j] + "&";
}
} else {
str += i + "=" + params[i] + "&";
}
}
//去掉最后一个“&”
str = str.substr(0, str.length - 1);
url = url + "?" + str;
}
}
var xhr = this.init("get", url, callBack);
xhr.send();
},
post: function () {
var url, params, callBack;
if (arguments.length == 2) {
url = arguments[0];
callBack = arguments[1];
} else if (arguments.length == 3) {
url = arguments[0];
params = arguments[1];
callBack = arguments[2];
}
var xhr = this.init("post", url, callBack);
//再来判断参数
if (params) {
if (typeof params == "string") {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(params);
} else if (typeof params == "object") {
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(params));
}
} else {
xhr.send();
}
}
})
})
}();
- 立即执行函数
- 对象特殊属性定义
- 冻结
- ajax基本使用以及参数格式的转换
Ajax的跨域问题
域是什么?origin
,它包含协议,主机地址,端口号
在之前讲BOM里面的localStorage
与sessionStorage
以及webSql
等缓存的时候,我们都提过,这些东西都不能跨域访问
Ajax本质上面也是不能跨域的
例如我的页面地址是https://127.0.0.1:5500/1ajax.html
,但是Ajax请求的地址是https://www.softeem.xin/maoyanApi/ajax/detailmovie
,这个时候,就发生了跨域的现像,一旦跨域现象,浏览就会报错,报一个Access-Control-Allow-Origin
CORS:跨域资源共享
ajax如果想实现跨域资源的调用,最简单的方法就是服务器实现CORS,只需要后台服务器在返回的时候添加如下请求头就可以了
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin: *
评论区