AJAX的使用

总结

  1. ajax使用步骤:

  • 1.创建XMLHttpRequest的实例对象
  let xhr = new XMLHttpRequest();
  • 2.打开与服务器之间的通道
  xhr.open(method, url,async);

其中:
method:请求方式
url:服务端的请求路径
async:是否异步请求(true:异步;false:同步)第三个参数可以省略 默认是true 异步

  • 3.发送请求
  xhr.send()

注意:get请求不传参数,只有post请求需要传递实体数据

  • 4.监听服务器的请求状态
    利用事件onreadystatechange完成回调

输出响应体数据结果
接收服务端响应到客户端的结果数据,可以有两种方式:response、responseText
如果服务端响应的数据为基本类型,那么使用response或者是responseText均可
如果服务端响应的数据为JSON对象的话,
方法1. 使用response获取对象数据,但是有一个前提需要设置响应数据类型为json xhr.responseType = 'json';
方法2. 使用responseText获取对象数据,那么无需设置响应数据类型,则需要手动通过JSON.parse方法将得到的JSON字符串转换成JSON对象 JSON.parse(xhr.responseText)

	//xhr.readyState 不同位置的状态
	
 	let xhr = new XMLHttpRequest();
    console.log(xhr.readyState); //0
    xhr.open('get', 'http://127.0.0.1:8080/users/time?title="标题1"&content="内容一"&time=' + Date.now())
    console.log(xhr.readyState)//1
    xhr.send(); 
    console.log(xhr.readyState);//1 发送后需要时间请求所以是1
    xhr.onreadystatechange = () => {
      console.log(xhr.readyState);//2 3 4
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status <= 300) {
          console.log(xhr.responseText)
        }
      }
    }
    
  xhr.onreadystatechange = function (){
  	//根据xhr对象的状态来进行判断
      //readyState:是xhr对象中的一个属性,属性值为0,1,2,3,4
      //0:表示xhr对象的建立初始化(实例化之后,open之前)
      //1:表示调用了open,完成了打开请求(open之后,send之前)
      //2:表示调用了send,完成了发送请求(send方法已经调用,但是当前的状态以及http头未知)
      //3:表示正在返回数据中
      //4:所有的数据完全响应完毕
      if(xhr.readyState: == 4){
          //status:xhr中的一个属性,表示响应状态码
          if(xhr.status == 200){
          	  console.log(xhr.response);//表示响应体的结果
              console.log(xhr.responseText);//表示响应体的结果
              console.log(xhr.status); //输出响应状态码
              console.log(xhr.statusText); //响应状态字符串
              console.log(xhr.getAllResponseHeaders());//获取所有响应头
              //得到某一个响应头信息
              console.log(xhr.getResponseHeader('Content-Type'))
              console.log(xhr.getResponseHeader('content-length'))
          }
      }
  }
  1. post请求需要设置请求头

    XMLHttpRequest.setRequestHeader(header,value)

    设置 HTTP 请求头的值。必须在 open() 之后、send() 之前调用 setRequestHeader() 方法

    header: 规定头的名称
    value: 规定头的值

目前接触到的常见头:
Content-Type:text/html;charset=utf-8 => 传送的内容既可以是普通文本,也可以是带标签的文本(可以理解为类似于JS中的innerHTML)
Content-Type:text/plain;charset=utf-8 => 传送的内容为普通文本(可以理解为类似于JS中的innerText)
Content-Type:application/json;charset=utf-8 => 传送的数据格式为json对象 {键名:键值,键名:键值}
Content-Type:application/x-www-form-urlencoded;charset=utf-8 => post请求字符串格式:参数名=值&参数名=值

//post请求头为form设置请求头:(用来模拟form表单提交)
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1. ajax请求超时 超时会自动取消接口

xhr.timeout = 2000;  //2秒钟之内需要有响应,如果没有响应则执行超时函数
xhr.ontimeout = function () {
	alert('不好意思,请求超时了,请等待重试!!');	
}
  1. ajax取消请求

	xhr.abort();//取消请求

在这里插入图片描述

跨域设置

  app.get('/server',(request,response)=>{
      //允许来自于不同的主机来向我发送跨域请求,必须设置
      response.setHeader('Access-Control-Allow-Origin','*');
      //允许在请求过程中客户端添加自定义请求头,如果不添加只能使用http中默认的一些请求头
      //例如:想要添加a:100就不行,所以这句话需要设置上
      response.setHeader('Access-Control-Allow-Headers','*'); 
      //允许所有的请求方法
      response.setHeader('Access-Control-Allow-Methods','*'); 
      //设置响应体
      response.end('server');
  });

ajax在IE中的缓冲问题以及解决方法

在IE浏览器中只要成功的请求响应过结果一次,就会将结果缓存在浏览器中,即使服务端响应的结果更新了;

客户端请求到的数据仍然是上一次的结果,解决办法只需要每一次发送请求时添加时间戳。

	xhr.open('get', 'http://127.0.0.1/server?time=' + Date.now());

设置CORS跨域


 app.get('/server',(request,response)=>{
      //允许来自于不同的主机来向我发送跨域请求,必须设置
      response.setHeader('Access-Control-Allow-Origin','*');
      //允许在请求过程中添加自定义请求头,如果不添加只能使用http中默认的一些请求头
      //例如:想要添加a:100就不行,所以这句话需要设置上
      response.setHeader('Access-Control-Allow-Headers','*'); 
      //设置响应体
      response.end('server');
  });

ajax同步的方法

let xhr = new XMLHttpRequest();
xhr.open('get', 'http://127.0.0.1:8080/users/time?title="标题1"&content="内容一"&time=',false)
xhr.send();
console.log(xhr.responseText)

AJAX

一、什么是ajax 阿贾克斯

ajax全称为Asynchronous javascript and xml,就是异步的js和xml;

目的是通过ajax可以在浏览器中向服务器发送异步请求,而最大的优势就是可以整体页面无刷新的获取数据

ajax不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式(JS中的一种API + 发送的http请求)。

例如:百度关键词搜索、用户名的唯一性验证、新闻的异步加载

二、什么是XML

XML是一种可扩展标记语言,用来被设计传输和存储数据;

和HTML类似,不同的是,HTML都是预定义标签,XML中全都是自定义标签来表示一些数据。

例如:

有一组学生的数据:

var name = "孙悟空";
var age = 18;
var gender = "男";

用XML表示:

<student>
	<name>孙悟空</name>
    <age>18</age>
    <sex></sex>
</student>
<student>
	<name>猪八戒</name>
    <age>20</age>
    <sex></sex>
</student>

<stu>
	<xingming a="1">张三</xingming>
</stu>

当然,现在已经被JSON格式所取代了。

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

三、使用原生的AJAX

核心对象:XMLHttpRequest,AJAX的所有操作都是通过该对象进行的。

3.1 使用步骤

  • 创建XMLHttpRequest的实例对象
  var xhr = new XMLHttpRequest();
  • 设置请求信息
  xhr.open(method, url);

其中:

method:请求方式

url:服务端的请求路径

  • 发送请求
  xhr.send()

注意:get请求不传参数,只有post请求需要传递实体数据

  • 接收响应

    利用事件onreadystatechange完成回调

  xhr.onreadystatechange = function (){
  	//根据xhr对象的状态来进行判断
      //readyState:是xhr对象中的一个属性,属性值为0,1,2,3,4
      //0:表示xhr对象的建立初始化
      //1:表示调用了open,完成了打开请求
      //2:表示调用了send,完成了发送请求
      //3:表示正在返回数据中
      //4:所有的数据完全响应完毕
      if(xhr.readyState: == 4){
          //status:xhr中的一个属性,表示响应状态码
          if(xhr.status == 200){
              console.log(xhr.responseText);//表示响应体的结果
              console.log(xhr.status); //输出响应状态码
              console.log(xhr.statusText); //响应状态字符串
              console.log(xhr.getAllResponseHeaders());//获取响应头
          }
      }
  }

3.2 ajax的初体验

案例:点击按钮发送ajax请求

<body>
    <button>点击发送一个ajax的get请求</button>
    <script>
        //1.获取DOM元素对象
        let btn = document.querySelector('button');
        //2.设置事件回调
        btn.onclick = ()=>{
            //3.创建ajax对象
            let xhr = new XMLHttpRequest();
            //4.打开请求
            xhr.open('get','http://127.0.0.1/server');
            //5.发送请求
            xhr.send();
            //6.客户端接收服务端的响应
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    if(xhr.status == 200){
                        console.log(xhr.responseText);
                    }
                }
            }
        }
    </script>
</body>
//1.引入express
const express = require('express');
//2.创建express对象
const app = express();
//3.设置请求url
app.get('/server',(request,response)=>{
    //允许来自于不同的主机来向我发送跨域请求,必须设置
    response.setHeader('Access-Control-Allow-Origin','*');
    response.send('hello ajax');
})
//4.监听端口并启动服务
app.listen(80,()=>{
    console.log('80端口已经启动');
})

3.3 ajax的GET传参问题

  • 在请求的url中传递参数
http://127.0.0.1/server?vip=1&keyword=abc&price=2000
  • 引入fs模块
const fs = require('fs');
  • 添加express的全局中间件
app.use(function(request,response,next){
	fs.writeFileSync('./access.log',request.url + "\r\n");
	next();
});

案例:仿留言板发送请求数据

<body>
    <p>昵称:<input type="text" id="user" /></p>
    <p>信息:<textarea cols="30" rows="10" id="content"></textarea></p>
    <p><button id="sendBtn">发送</button></p>
    <script>
        //1、获取元素对象
        let sendBtn = document.querySelector('#sendBtn');
        //2、绑定事件
        sendBtn.addEventListener('click', () => {
            //3、获取表单信息
            let nickName = document.querySelector('#user').value;
            let content = document.querySelector('#content').value;
            //4、ajax发送请求
            let xhr = new XMLHttpRequest();
            xhr.open('get', `http://127.0.0.1/server?nickName=${nickName}&content=${content}`);
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status == 200) {
                        console.log(xhr.responseText);
                    }
                }
            }
        });
    </script>
</body>
//引入express
const express = require('express');
//创建服务对象
const app = express();

//引入fs文件系统模块
const fs = require('fs');

//添加express的全局中间件
app.use((request,response,next)=>{
    //创建文件保存客户端传递的请求参数数据
    //服务端接收客户端传递的请求参数数据
    console.log(request.url);
    fs.writeFileSync('./data.log', decodeURI(request.url) + '\r\n',{flag:'a'});
    next();
});

//创建路由规则
app.get('/server',(request,response)=>{
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');    
    response.send('ajax请求');
});
//监听端口
app.listen(80,()=>{
    console.log('80端口正在启动中...ing');
});

3.4 ajax请求头与请求体的设置

如何发送post请求

<style>
        div {
            width: 300px;
            height: 300px;
            border: 1px solid red;
        }
</style>
<body>
    <div></div>
    <script>
        //1、获取元素
        let div = document.querySelector('div');
        //2、绑定事件
        div.onclick = function () {
            //3、创建ajax对象
            const xhr = new XMLHttpRequest();
            xhr.open('post', 'http://127.0.0.1/server');
            //4、设置请求头
            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            //5、设置请求体数据
            xhr.send('vip=9&wd=abc');

            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //将响应体的结果在div中呈现
                        div.innerText = xhr.responseText;
                    } else {
                        alert('请求失败');
                    }
                }
            }
        }
    </script>
</body>

3.5 ajax在IE中的缓冲问题以及解决方法

在IE浏览器中只要成功的请求响应过结果一次,就会将结果缓存在浏览器中,即使服务端响应的结果更新了;

客户端请求到的数据仍然是上一次的结果,解决办法只需要每一次发送请求时添加时间戳。

xhr.open('get', 'http://127.0.0.1/server?time=' + Date.now());

3.6 ajax中json格式数据的处理

mime类型:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

需求:文本框失焦时发送ajax请求

3.6.1 手动转换
<body>
    <input type="text">
    <span></span>
    <script>
        //1、获取元素
        let ipt = document.querySelector('input');
        let span = document.querySelector('span');
        //2、绑定失焦事件
        ipt.onblur = function () {
            //3、发送ajax请求
            const xhr = new XMLHttpRequest();
            xhr.open('get', 'http://127.0.0.1/json-server');
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        //将json字符串转换成json对象
                        const data = JSON.parse(xhr.responseText);
                        //判断
                        if (data.errno == 1) {
                            ipt.style.border = "1px solid red";
                            span.innerText = data.errmsg;
                        }

                    }
                }
            }
        }
    </script>
</body>
app.get('/json-server',(request,response)=>{
    //响应结果 json格式的响应体
        let data = {
            errno : 1,
            errmsg : '用户名已经存在'
        }
    //将json对象转换成json字符串
    let str = JSON.stringify(data);
    //允许来自于不同的主机来向我发送跨域请求,必须设置
    response.setHeader('Access-Control-Allow-Origin','*');
    //设置响应体
    response.end(str);
});
3.6.2 自动转换

第一步:预先设置响应体的结果类型为json

xhr.responseType = 'json';

第二步:获取响应体数据使用response

console.log(xhr.response); #在这里response会根据设置类型自动变化;responseText始终为响应字符串

案例1:网络列表数据的获取

<body>
    <button>点击获取数据列表</button>
    <ul></ul>
    <script>
        //获取元素
        let btn = document.querySelector('button');
        let ul = document.querySelector('ul');
        //2、绑定事件
        btn.addEventListener('click', () => {
            const xhr = new XMLHttpRequest();
            xhr.responseType = 'json';
            xhr.open('get', 'http://iwenwiki.com/api/blueberrypai/getIndexTravelnote.php');
            xhr.send();
            xhr.onreadystatechange = function () {
                //判断
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        let data = xhr.response;
                        data.travelnote.forEach(item => {
                            //创建li节点对象
                            let liNode = document.createElement('li');
                            //修改li标签的文本
                            liNode.innerText = item.title
                            //ul追加
                            ul.appendChild(liNode);
                        })
                    }
                }
            }
        });
    </script>
</body>

案例2:天气数据的查询

注:http://tianqiapi.com/ 需要提前注册

    <style>
        #result {
            width: 300px;
            height: 200px;
            border: 1px solid #222;
        }
    </style>
</head>

<body>
    <input type="text">
    <button>点击查询</button>
    <hr>
    <div id="result"></div>
    <script>
        //1、获取元素对象
        let ipt = document.querySelector('input');
        let btn = document.querySelector('button');
        let result = document.querySelector('#result');
        //2、绑定事件
        btn.addEventListener('click', () => {
            let cvalue = ipt.value;
            //3、创建ajax请求
            let xhr = new XMLHttpRequest();
            xhr.responseType = 'json'
            xhr.open('get', 'https://spot.yiketianqi.com/?action=city&appid=82294778&appsecret=4PKVFula&province=%E5%B9%BF%E4%B8%9C&city=%E6%B7%B1%E5%9C%B3');
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        let data = xhr.response;
                        console.log(data);
                    }
                }
            }
        })
    </script>
</body>

3.7 ajax请求超时

xhr.timeout = 2000;  //2秒钟之内需要有响应,如果没有响应则执行超时函数
xhr.ontimeout = function () {
	alert('不好意思,请求超时了,请等待重试!!');
}

3.8 ajax取消请求

<body>
    <button id="timeout">发送超时请求</button>
    <button id="cancel">取消请求</button>
    <script>
        //1、获取元素
        let timeout = document.querySelector('#timeout');
        let cancel = document.querySelector('cancel');
        let xhr; //注意这里不能使用const,因为需要有初始化的值
        //2、绑定事件
        timeout.onclick = function () {
            //也可以判断是否正在发送
            if (xhr) {
                xhr.abort();
            }
            //3、发送ajax请求
            xhr = new XMLHttpRequest();
            xhr.open('get', 'http://127.0.0.1/delay-server');
            xhr.send();
            //超时时间设置
            xhr.timeout = 3000;
            xhr.ontimeout = function () {
                alert('对不起 请求超时 请重试');
            }
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                    }
                }
            }
        }


        cancel.onclick = function () {
            xhr.abort();
        }

    </script>
</body>
app.get('/delay-server',(request,response)=>{
    setTimeout(()=>{
        response.send('delay');
    },3000);
});

四、ajax的请求跨域问题

4.1 同源策略

同源策略(Same-Origin Policy)最早由Netspace公司提出,是浏览器的一种安全策略。

同源是指协议域名端口号都必须完全相同,两个资源必须来自于同一个服务,

如果违背上述任何一个条件就是跨域

4.2 如何解决跨域

4.2.1 JSONP
  • JSONP是什么

JSONP(JSON with Padding),是一个非官方的跨域解决方案,

纯粹凭借程序员的聪明才智开发出来,只支持get请求

  • JSONP怎么工作的?

在网页有一些标签天生具有跨域能力,比如 img、link、iframe、script

JSONP就是利用script标签的跨域能力来发送请求的

  • JSONP的使用

    动态的创建一个script标签

  var script = document.createElement('script');

设置script的src,设置回调函数

  script.src = "http://127.0.0.1/jsonp-server?cb=handler";
  function handler(data) {
  	console.log(data);
  };

将script添加到body中

  document.body.appendChild(script);

在服务端定义url路由规则

app.get('/jsonp-server',(request,response)=>{
	let data = '此用户名已经存在';
	let cb = request.query.cb;
	response.end(`${cb}("${data}")`);
})

案例:客户端发送jsonp跨域请求

<body>
	<button>发送jsonp跨域请求</button>
	<p></p>
	<script>
    	//声明一个函数(回调函数),函数的作用是对响应体结果进行处理
    	function handler(data){
    		//将响应结果显示到p标签中
    		document.querySelector('p').innerHTML = data;
		}
    	let btn = document.querySelector('button');
		btn.onclick = function(){
            //创建script标签
            let script = document.createElement('script');
            //修改script标签的src属性
            script.src = "http://127.0.0.1/jsonp-server?cb=handler";
            //将script标签添加到body中
            document.body.appendChild(script);
        }
    </script>
</body>
  • jquery发送JSONP请求

    <head>
        <title>jquery发送jsonp请求</title>
    	<script type="text/javascript" src="./jquery-1.12.4.js"></script>    
    </head>
    <body>
    	<button>jquery发送jsonp请求</button>
    	<script>
        	//获取元素对象
        	let btn = document.querySelector('button');
    		//绑定事件
    		btn.onclick = function(){
                $.getJSON('http://127.0.0.1/jsonp-server?cb=?',function(data){
                    console.log(data);
                })
            }
        </script>
    </body>
    
4.2.2 CORS
  • 什么是CORS

    CORS(Cross-Origin Resource Sharing),跨域资源共享。

    CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作

    完全在服务器中进行处理,支持get和post请求

  • CORS是如何工作的

    CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。

  • CORS的使用

    只需要在服务端中设置响应头

  app.get('/server',(request,response)=>{
      //允许来自于不同的主机来向我发送跨域请求,必须设置
      response.setHeader('Access-Control-Allow-Origin','*');
      //允许在请求过程中添加自定义请求头,如果不添加只能使用http中默认的一些请求头
      //例如:想要添加a:100就不行,所以这句话需要设置上
      response.setHeader('Access-Control-Allow-Headers','*'); 
      //设置响应体
      response.end('server');
  });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值