Ajax的概述与使用,包含fetch(),axios,跨域

1.1 Ajax概述

1.1.1 Ajax 简介

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。 AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。默认遵循同源策略

1.1.2 XML 简介

XML 即可扩展标记语言。XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签, 全都是自定义标签,被设计用来传输和存储数据

比如说我有一个学生数据:
name = "孙悟空" ; age = 18 ; gender = "男" ;
用 XML 表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender></gender>
</student>

现在已经被 JSON 取代

JSON 表示:
{"name":"孙悟空","age":18,"gender":"男"}

1.1.3 Ajax 的特点

Ajax 的优点

  • 可以无需刷新页面而与服务器端进行通信。

  • 允许你根据用户事件来更新部分页面内容。

Ajax 的缺点

  • 没有浏览历史,不能回退(局部更新)
  • 存在跨域问题(请求可能不同源)
  • SEO 不友好(源代码中找不到某些信息)

1.2 Ajax 的使用

1.2.1 核心对象

  • XMLHttpRequest,Ajax 的所有操作都是通过该对象进行的。

1.2.2 使用步骤

//1,创建 XMLHttpRequest 对象
let xhr = new XMLHttpRequest()

// 设置响应体数据的类型(因为服务器只能传送字符串),后续接收的字符串自动处理了
//xhr.responseType = 'json';  
// 手动对数据转化  let data = JSON.parse(xhr.response);


//2,初始化,设置请求信息
// xhr.open(method,url)  
xhr.open('POST','http://127.0.0.1:8000/serve?a=1&b=2')  //可设置请求参数
//xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');  设置请求头

//3,发送请求
//xhr.send(body)  get请求不传送body参数,只有post请求使用
xhr.send('a=100&b=200&c=300+1234567')  //设置请求体 

//4,接收响应
// xhr.responseXML  接收XML格式的响应数据
// xhr.responseText 接收文本格式的响应数据
xhr.onreadystatechange = function(){
    if(xhr.readyState===4){  //响应状态码 
	   if(xhr.status>=200 && xhr.status<300){
           console.log(xhr.response)//响应体
       }
    }
}

1.2.3 Ajax 响应状态码

即XMLHttpRequest.readyState属性

0 UNSENT : XMLHttpRequest 代理已被创建, 但尚未调用 open() 方法。

1 OPENED : open() 方法已经被触发。在这个状态中,可以通过 setRequestHeader() 方法来设置请求的头部, 可以调用 send()方法来发起请求。

2 HEADERS_RECEIVED : send() 方法已经被调用,响应头也已经被接收。

3 LOADING : 响应体部分正在被接收。如果 responseType 属性是“text”或空字符串, responseText 将会在载入的过程中拥有部分响应数据。

4 DONE : 请求操作已经完成。这意味着数据传输已经彻底完成或失败。

1.2.4 请求超时与网络异常

const xhr = new XMLHttpRequest();

//超时设置 2s ,超过2s没收到系统回复即取消请求
xhr.timeout = 2000;  

//超时回调 ,超时后启动
xhr.ontimeout = function(){
    alert("网络异常, 请稍后重试!!");
}

//网络异常回调
xhr.onerror = function(){
    alert("你的网络似乎出了一些问题!");
}
...

1.2.5 取消请求与重复请求

XMLHttpRequest.abort() 方法可以取消发送的请求

当重复点击发起重复请求时,为避免浪费资源,启动防抖,即取消前面的请求,只保留最新的请求

let flag = false; // 是否正在发送AJAX请求

btns[0].onclick = function(){
    //判断标识变量
    if(flag) x.abort();  //如果正在发送, 则取消该请求, 创建一个新的请求
    x = new XMLHttpRequest();
    flag = true;  //修改 标识变量的值
    x.open("GET",'http://127.0.0.1:8000/serve');
    x.send();
    x.onreadystatechange = function(){
        if(x.readyState === 4){
            //修改标识变量
            isSending = false;
            ...
        }
    }
}

1.2.6 解决IE缓存问题

​ 问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求, 剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。

​ 解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址即可避免缓存问题

xhr.open("get","/testAJAX?t="+Date.now());

1.3 axios 中使用Ajax

//以下是引入axios后的用法,只展示使用部分
//配置 baseURL,即下面所有路径默认前面加上此url
axios.defaults.baseURL = 'http://127.0.0.1:8000';

//axios发送请求的示例,常用  axios(config),axios(url[, config])
    axios({
        //请求方法  默认get
        method : 'POST',
        //url
        url: '/axios-server',
        //url参数
        params: {pa: 'pa'},
         //请求头信息,若是自写头,需服务器提供权限
        headers:{head: 'head'},
        //请求体参数
        data: {
            username: 'admin',password: 'admin'}
    }).then(response=>{
        console.log(response.status);  //响应状态码
        console.log(response.statusText ; //响应状态字符串
        console.log(response.headers); //响应头信息
        console.log(response.data);  //响应体
    })

//axios发送get请求的示例  axios.get(url[, config])
    axios.get('/axios-get-server', {
        params: {pa: 'pa'},
        headers: {head: 'head'}
    }).then(value => {
        //对返回数据的处理
        console.log(value);
    });

//axios发送post请求的示例  axios.post(url[, data[, config]])
    axios.post('/axios-post-server', {
        //请求体内容
        username: 'admin',password: 'admin'
    }, {
        params: {pa: 'pa'},
        headers: {head: 'head'}
    }).then(value => {
        console.log(value);
    })

1.4 fetch()方法使用Ajax

fetch('http://127.0.0.1:8000/fetch-server?k=1', {
    //请求方法
    method: 'POST',
    //请求头
    headers:{head: 'head'}//请求体
    body: 'username=admin&password=admin'
}).then(response => {
    // 此时形参response是Response对象
    return response.json();
    //该方法可读取 Response 对象并且将它设置为已读(因为 Responses 对象被设置为了 stream 的方式,所以它们只能被读取一次),并返回一个被解析为 JSON 格式的 Promise 对象。
}).then(response=>{
    // 此时形参response是Promise对象的值
    console.log(response);
});

ajax 属 js 原生,基于XHR(即XMLHttpRequest对象)进行开发,XHR 结构不清晰,容易生成回调地狱。

fetch方法属于原生 js,脱离了XHR,支持Promise,但兼容性较差,和有其他问题。

目前一般使用axios,本质还是 ajax,即XHR,基于 Promise 进行封装,既解决回调地狱问题,又能很好地支持各个浏览器。

1.5 跨域

同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。同源即 协议、域名、端口 必须完全相同。浏览器出于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读取对方的资源。主要用来防止CSRF(跨站请求伪造)攻击。

违返浏览器的同源策略就是跨域。 解决同源策略的方案有:jsonp,iframe,CORS,webscoket,代理服务器等。

1.5.1 jsonp

JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持 get 请求。在网页有一些标签天生具有跨域能力,比如:img link iframe script。 JSONP 就是利用 script 标签的跨域能力来发送请求的。

JSONP 的使用:

//1.动态的创建一个 script 标签
let script = document.createElement("script");
//2.设置 script 的 src 属性,只要服务器中返回的是JS代码即可
 script.src = "http://localhost:8000/testAJAX?callback=abc"
//3.将 script 添加到 dom 中
document.body.appendChild(script); 

1.5.2 CORS

CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源

具体操作:CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应 以后就会对响应放行。主要是服务器端的设置

//下面的代码在node.js的express内使用
router.get("/testAJAX" , function (request , response) {
	//通过 response 来设置响应头,来允许跨域请求
	//response.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
	response.setHeader("Access-Control-Allow-Origin","*");  //随便跨域
    response.setHeader('Access-Control-Allow-Headers', '*') //随便请求头
})
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羊and船

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值