赞
踩
Ajax 全称 Asynchronous JavaScript And XML 及异步JS与XML,其主要原理是使用XMLhttpRequest对象完成前后端交互,
它通过状态码readyState区别当前状态,分别为
0.未定义
1.载入中
2.载入完成
3.交互中
4.交互完成
可通过状态码改变执行操作,而平时使用的ajax都是封装好的一个程序,他的封装过程如下:
1.获取请求对象,内部应当包含请求类型,接口url和上传服务器的数据
2.新建httpRequest对象
let xhr = new XMLHttpRequest()
3.将请求配置参数赋值给httpRequest对象
xhr.open('get', obj.url + toValue(obj.data), obj.isAsync)
4.发送
xhr.send()
5.状态更改回调检测到数据返回并执行相应操作
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- 解析后端返回数据
- }
- }
一个简单的ajax封装应当是这样的
- //封装一个ajax 即XMLHttpRequest
-
- /*
- 使用说明
- 以一下格式发送数据
- ajax({
- url: '/login',
- method: 'get',
- data: {
- username:'xh1001',
- password:'T01'
- },
- isAsync: 'true',
- success:function(res){
- console.log("res:",res.data);
- },
- error:function(err){
- console.log("err:",err);
- }
- })
- */
-
-
- /*分割线************************ */
- function ajax(obj) {
- //判断接口是否为空
- if (!obj.url) {
- return;
- }
-
- //1.数据检查及补充
- //请求种类,默认为get
- obj.method = obj.method || 'get'
- //是否异步,默认为true
- obj.isAsync = obj.isAsync || 'ture'
- //是否有数据,没有默认补充为空对象
- obj.data = obj.data || {}
-
- // 2.准备ajax
- let xhr = new XMLHttpRequest() || new ActiveXObject()//ie兼容
-
- // 发送get或者post
- if (obj.method === 'get') {
- // 准备发送数据
- xhr.open('get', obj.url + toValue(obj.data), obj.isAsync)
- // 发送get
- xhr.send()
- } else if (obj.method === 'post') {
- // 准备发送数据
- xhr.open('post', obj.url, obj.isAsync)
- // 配置请求头content-type 申明数据以什么方式解析数据(json)
- xhr.setRequestHeader('Content-type', 'application/json')
- // 配置请求头content-type 申明数据以什么方式解析数据(表单数据)
- // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
-
- // 发送post(json)
- xhr.send(JSON.stringify(obj.data))
- // 发送post(表单数据)
- // xhr.send(toValue(obj.data))
- }
-
- // 检测readyState判断是否将数据传回
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
- //返回数据已obj的success回调函数输出
- // console.log('====',xhr.responseText);
- // obj.success(JSON.parse(xhr.responseText))
- // obj.success(xhr.responseText)
- // 检测cookie,如果cookie无效将执行
- if (JSON.parse(xhr.responseText).code === 201) {
- console.log(JSON.parse(xhr.responseText));
- .....
- } else {
- obj.success(JSON.parse(xhr.responseText))
- }
- } else {
- obj.error('unknowError')
- }
- }
- }
-
- }
-
-
- //前端数据拼接为表单格式
- const toValue = function (obj) {
- let str = '?'
- for (let key in obj) {
- str += `${key}=${obj[key]}&`
- }
- return str.slice(0, str.length - 1)
- }
其中 // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')这里的setRequestHeader其实是对请求头进行配置,而Content-type具体是对请求的数据解码方式进行说明,以便后端服务器处理数据,
常用的有application/x-www-form-urlencoded(原生form表单)、application/json(json数据)、multipart/form-data(带文件上传功能得数据盒子,一个对象)
这样在页面中只要调取ajax({datas})程序 ,就可以发送ajax请求了
当然数据的处理不是一概而论的,所以我们在发送ajax时输入的对象中配置成功或失败的回调(这里只针对返回的数据而言成功与否,并不是对ajax请求)
- ajax({
- url: '/studentCodeChange',
- method: 'post',
- data: {
- id: nowUser.s_id,
- oldCode: oldCode,
- newCode: newCode
- },
- success: function (data) {
- console.log("data", data);
- // 清空输入框
- alert('修改密码成功')
- $('#codeChangeLab').css('display', 'none')
- $('#oldCode').val('')
- $('#newCode').val('')
- $('#reCode').val('')
-
- },
- error: function (err) {
- console.log('err', err);
- alert('查询失败,请稍后尝试')
- }
- })
axios本身是对ajax而言的一个二次封装,相比原生Ajax,它用到了promise技术,从而改变了ajax需要多次调用时的尴尬,在成功之后我们可以用.then().catch()轻易进行链式调用,使得代码可读性更高,同时promise可以更方便地对请求本身进行修改,从而很好地解决了身份验证,地址传值等处的代码量,我们在使用时可以简单地调用它,也可以进行复杂的逻辑操作。
一个简答的axios请求是这样的:
- const axios= axios.create({
- baseURL: '/api', // 给axios请求的 url 前面加一个 '/api'
- timeout: 5000, //整体设置axios的请求超时时间
- // headers: {'X-Custom-Header': 'foobar'} //整个加请求头
- })
-
- axios({
- url: '/SystemSetting/login',
- method:'post',
- data: data
- }).then((res)=>{
-
- do sth......
- })
-
-
- axios({
- url: '/SystemSetting/login',
- method:'get',
- params: data
- }).then((res)=>{
-
- do sth......
- })
正如上面所说的 ,我们可以对axios进行一定的封装,通常封装的目的是
1.配置baseUrl
通常项目开发时,需要跨域,在我们设置了跨域服务器后,请求也需要向对方服务器发送,所以要配置一个变量作为请求头,而这里的baseUrl激素hi为了统一配置方便开发,开发完成后置空或者删除再部署到服务器
2.拦截器配置
axios.interceptors.request.use
3.设置延迟时间
请求不能一直等待,当到达一定时限后要取消发送并返回请求超时
- import axios from 'axios'
-
-
- const http = axios.create({
- baseURL: '/api', // 给axios请求的 url 前面加一个 '/api'
- timeout: 5000, //整体设置axios的请求超时时间
- // headers: {'X-Custom-Header': 'foobar'} //整个加请求头
- });
-
- // 以下是拦截器
- //拦截请求 use 接收两个参数 第一个是请求成功的回调函数,第二个请求失败的回调函数
- http.interceptors.request.use(function (req) {
- //再整整发起请求前的操作
- // console.log('req',req);
- //如果有token的话,就携带上,没有不携带
- if(localStorage.getItem('token')){
- //携带在请求里面
- req.headers['token'] = localStorage.getItem('token')
- }
-
-
- return req; //放行
- }, function (error) {
- // Do something with request error
- return Promise.reject(error);
- });
-
- //拦截响应
- http.interceptors.response.use(function (res) {
- //响应回来 做的操作
- // console.log('相应回来的数据',res);
-
- //存token
- if(res.data.data && res.data.data.token){
- localStorage.setItem('token',res.data.data.token)
- }
- //简写
- // res.data.token && localStorage.setItem('token',res.data.token)
-
- //判断res里面有没有token,有的话就存起来,没有就不管
-
- return res; //放行
- },
- function (error) {
- console.log('err111',err);
- //判断一下响应的状态码
- if(error.response.status === 401){
- alert('身份过期 没有携带token')
- //把token清除掉
- localStorage.removeItem('token')
- //跳转到等录取 重新验证身份
- }
- return Promise.reject(error);
- }
- );
-
-
-
-
-
- export default http
fetch是基于promise的一个原生语法糖,关于他的用法,官方给出了一个很完善的例子
- // Example POST method implementation:
- async function postData(url = '', data = {}) {
- // Default options are marked with *
- const response = await fetch(url, {
- method: 'POST', // *GET, POST, PUT, DELETE, etc.请求方式
- mode: 'cors', // no-cors, *cors, same-origin 是否开启代理
- cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached缓存
- credentials: 'same-origin', // include, *same-origin, omit是否同源
- headers: {
- 'Content-Type': 'application/json'数据类型
- // 'Content-Type': 'application/x-www-form-urlencoded',
- },
- redirect: 'follow', // manual, *follow, error重定向
- referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
- body: JSON.stringify(data) // body data type must match "Content-Type" header同请求头
- //格式
- });
- return response.json(); // parses JSON response into native JavaScript objects
- }
-
- postData('https://example.com/answer', { answer: 42 })
- .then(data => {
- console.log(data); // JSON data parsed by `data.json()` call
- });
一般使用的时候还是要封装,我们再举一个简单的封装案例:
- function http({url,method,data={},headers={}}){
- console.log(method)
- console.log(data)
-
- if(!url){
- return
- }
-
- // 常用请求头
- headers["Content-type"] = "application/json"
- headers["token"] = "token@@@@@"
-
- if(method.toLowerCase()==="get"){
- data = JSONtoUrl(data)
- console.log("getting")
- let newUrl = url+'?'+data
- let init = {method:"get"}
- return fetch(newUrl,init).then((res)=>{res.json()})
- }else{
- console.log("posting")
- let init = {
- method:"post",
- body:JSON.stringify(data),
- headers
- }
- console.log(init)
- console.log(init.body)
- return fetch(url,init).then((res)=>{res.json()})
- }
-
-
- }
-
- function JSONtoUrl(json){
- let str = ''
-
- for(let k in json){
- str += `${k}=${json[k]}&`
- }
-
- str = str.substring(0,str.length-1)
-
- return str
- }
-
- export default http
这里要注意这一步不能少
.json的作用是将promise对象解析为一个接送对象,官方的说法是fetch返回的是一个完整的http请求的相应格式,并不能直接被我们使用,这里就需要他们设定的json()方法进行解析,由于基于promise,我们直接将其封装在返回值内,这样就可以直接得到后端原本发给我们的数据了。
return fetch(newUrl,init).then((res)=>{res.json()})
封装后发送
- let packageGet = ()=>{
- http({
- url:'x',
- method:'get',
- data:{name:"sss",age:18},
- }).then((res)=>{
- console.log(res)
- })
- }
-
- let packagePost = ()=>{
- http({
- url:'x',
- method:'post',
- data:{"name":"xxx","age":"18"},
- }).then((res)=>{
- console.log(res)
- })
- }
一个fetch
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。