一、什么是AJAX

1.ajax定义

AJAX = Asynchronous JavaScript and XML(异步的JavaScript和XML)
ajax不是新的编程语言,而是一种使用现有标准的新方法
ajax最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容

2.同步和异步

同步就是客户端向服务器发送请求的过程中,用户不可以进行其他操作
异步就是客户端向服务器发送请求的过程中,用户可以进行其他操作
拿排队举例:

  • 同步:在银行排队时,只有等到你了,才能够去处理业务。
  • 异步:在排队的时候,可以玩手机。

    3.js实现原生ajax

    ajax是从服务器上获取数据的一种技术
    js实现原生的ajax分为四步:
    1.创建ajax核心对象XMLHttpRequest();
    2.与服务器建立连接,运用open方法
    3.发送请求,用send方法
    4.响应,渲染服务端的数据
    具体操作如下:

    1. //此url是模拟的一个服务器,这个url的地址就是要抓取数据的地址
    2. var url = "https://www.easy-mock.com/mock/5d67436424fd60626abfe91a/ajax/base";
    3. var xhr = new XMLHttpRequest(); //1.创建ajax核心对象
    4. xhr.open('get',url,true); //2.与服务器建立连接
    5. xhr.send(); //3.发送请求
    6. xhr.onreadystatechange = function () { //4.响应
    7. //readyState==4并且status==200时,表示连接成功
    8. if(xhr.readyState == 4 &&xhr.status == 200){
    9. var res =JSON.parse(xhr.responseText);
    10. console.log(res.data.name)
    11. var name = document.getElementById('name');
    12. name.innerHTML = res.data.name;
    13. }
    14. }

    4.onreadystatechange事件

    由上面原生ajax代码可知,当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当readyState改变时,就会触发onreadystatechange事件。readyState属性存有XMLHttpRequest的状态信息。
    下面是XMLHttpRequest对象的三个重要属性:
    image.png
    所以当readyState == 4且状态为200时,表示响应已就绪。

    二、jQuery实现ajax

    1.jQuery实现

    由于js实现原生ajax太过于繁琐,jQuery不仅仅简化了js,里面还封装了实现ajax的方法,于是用jQuery实现ajax会简单不少。

    1. <script>
    2. var url = "https://www.easy-mock.com/mock/5d67436424fd60626abfe912/ajax/base"
    3. $.ajax({
    4. url: url,
    5. type: "get",
    6. dataType: "json",
    7. //连接成功
    8. success: function (res) {
    9. console.log(res)
    10. $("#loading").hide()
    11. },
    12. //连接失败
    13. error: function (err) {
    14. console.log(err)
    15. },
    16. //发送之前
    17. beforeSend: function () {
    18. $("#loading").show()
    19. }
    20. })
    21. </script>

    用jQuery实现ajax时,只需$.ajax({…..}),将参数写在中括号里面;
    需要传服务器的地址url,请求的类型type,数据类型dataType;后面如果连接成功会得到一个res对象,里面就是拿到的json数据。

2.封装ajax

由于ajax格式固定,所以可以将其封装,需要的时候,只用传几个必要的参数即可调用
是将ajax封装在一个js文件里,并且引用链接的时候应该先引jQuery的,再引此封装的文件,因为这个封装方法里面用了jQuery的语法

封装ajax前需要了解三个知识点:默认赋值,回调函数,箭头函数

默认赋值

  1. /*
  2. 默认赋值:预先给函数的参数一个值
  3. */
  4. function go(type="get"){
  5. console.log(type)
  6. }
  7. go() //不给参数返回默认值,这里是get
  8. go("post") //给参数返回参数值,这里是post

回调函数

  1. /* 回调函数:就是将函数作为参数传递给另外一个函数
  2. 作用:可以获取函数内部的值
  3. */
  4. function http(callback){
  5. var data = {"name":"cheng",age:18};
  6. callback(data);
  7. }
  8. function hanleData(res){
  9. console.log(res)
  10. }
  11. http(hanleData); //此处由hanleData充当回调函数,通过它让外部获取到了http内部的数据

箭头函数

  1. //原函数
  2. var a = function(x){
  3. console.log(x)
  4. }
  5. //箭头函数
  6. var c = x=>{
  7. console.log(x)
  8. }
  9. //含两个参数的箭头函数
  10. var b = (x,y)=>{
  11. console.log(x+y)
  12. }

封装ajax

  1. /* 默认赋值,回调函数,箭头函数 */
  2. var url = "https://music.aityp.com/top/album?limit=35";
  3. function http({callback,data}) {
  4. $.ajax({
  5. url,
  6. type:"get",
  7. dataType:"json",
  8. data,
  9. success:res=>{
  10. callback(res);
  11. }
  12. })
  13. }
  14. //这是封装的判断是否到达底部的代码,加载刷新时用的
  15. function onReachBottom(){
  16. var scrollHeight = $(document).height();
  17. var scrollTop = Math.ceil($(document).scrollTop());
  18. var availHeight = $(window).height();
  19. return (scrollHeight == scrollTop+availHeight)?true:false;
  20. }

调用ajax

  1. var offset = 0;
  2. //发送http请求
  3. http({
  4. callback: handleData,
  5. data:{
  6. offset,
  7. }
  8. });
  9. //请求成功的回调函数
  10. function handleData(res) {
  11. ......}

三、跨域

1.什么是跨域

AJAX - 图2
当一个域名的协议、子域名、主域名、端口号这四个任意一个不相同的时候,就算是不同的域名。
跨域:不同域之间请求资源就算做是跨域。
Javascript出于安全性的考虑,不允许跨域调用其他页面的对象。简单理解就是因为Javascript同源策略的限制,a.com域名下的js无法操作b.com域名下的对象。
**

2.如何解决跨域

jsonp跨域

jsonp跨域其实也是JavaScript设计模式中的一种代理模式。在HTML页面中通过相应的标签从不同的域名下加载静态资源文件是被浏览器允许的,所以我们可以通过这个“犯罪漏洞”来进行跨域。一般,我们可以动态的创建script标签,再去请求一个带参网址来实现跨域通信。

js原生的实现方式:

  1. //原生的实现方式
  2. var url = "https://douban.uieee.com/v2/movie/top250";
  3. var script = document.createElement("script");
  4. script.src= url+"?callback=handleData";
  5. document.body.append(script)
  6. function handleData(res){
  7. console.log(res)
  8. }

jQuery的实现方式:

  1. var url = "https://douban.uieee.com/v2/movie/top250";
  2. $.ajax({
  3. url,
  4. type:"get",
  5. dataType:"jsonp", //这里数据类型改为jsonp就OK了
  6. success:res=>{
  7. console.log(res)
  8. }
  9. })

虽然这种方式非常好用,但是一个最大的缺陷是,只能够实现get请求。

postMessage()方法

postmessage()方法是H5中新增的方法
场景:窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息,步骤如下
(1)在A窗口中操作如下:向B窗口发送数据:

  1. // 窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
  2. Bwindow.postMessage('data', 'http://B.com'); //这里强调的是B窗口里的window对象

(2)在B窗口的操作如下:

  1. // 在窗口B中监听 message 事件
  2. Awindow.addEventListener('message', function (event) { //这里强调的是A窗口里的window对象
  3. console.log(event.origin); //获取 :url。这里指:http://A.com
  4. console.log(event.source); //获取:A window对象
  5. console.log(event.data); //获取传过来的数据
  6. }, false);

服务器的解决方案

AJAX - 图3

四、ajax的应用

1.读取豆瓣电影图片

需要实现效果如下图所示
image.png

请求成功获取豆瓣接口的数据

  1. var url ="https://douban.uieee.com/v2/movie/top250";
  2. $.ajax({
  3. url,
  4. type:"get",
  5. dataType:"jsonp",
  6. success:res=>{
  7. console.log(res);
  8. }
  9. })

打印出获取的数据,首先要看清这个json对象的数据结构,我们需要的是电影的标题和图片都在subject数组里面
image.png

于是打开此数组找需要获取的数据
image.png

将需要的数据装进数组中

  1. success:res=>{
  2. var movie = []; //创建一个数组来装需要获取的指定数据
  3. var subjects = res.subjects;
  4. for(var i in subjects){
  5. var obj = {};
  6. obj.imageUrl = subjects[i].images.small;
  7. obj.title = subjects[i].title;
  8. movie.push(obj);
  9. }
  10. console.log(movie);
  11. }

打印此数组得到的结果
image.png

将得到的数据渲染在页面中

  1. for(var j =0;j<movies.length;j++){
  2. var item = $(`<div>
  3. <img src="${movies[j].imageUrl}"/>
  4. <p>${movies[j].title}</p>
  5. </div>`)
  6. $("body").append(item)
  7. }

注意:渲染页面的$()里的元素是用``包裹的

2.网易云搜索播放

实现此功能需要的接口如下:

  1. https://music.aityp.com/search?keywords=input.value; //获取键盘输入的歌曲名,得到歌曲id
  2. https://music.aityp.com/song/detail?ids=85580 //获取歌曲详情,根据id得到imgUrl
  3. https://music.aityp.com/song/url?id=85580 //根据id得到音乐播放源

键盘回车触发事件获取输入值

  1. //onkeydown表示键盘按键触发的事件
  2. input.onkeydown = function(event){
  3. //回车的键码为13,故当回车的时候,发送http请求,请求获取数据
  4. if(event.keyCode == 13){
  5. console.log(this.value)
  6. /* 1.获取id */
  7. $.ajax({
  8. url:`${url}search?keywords=${this.value}`,

image.png

将输入的值放在url尾部发送http请求

这一步知识为了得到歌曲的id,有了id就可以通过后面两个接口得到歌曲的img和播放源。

  1. $.ajax({
  2. url:`${url}search?keywords=${this.value}`,
  3. type:"get",
  4. dataType:"json",
  5. success:res=>{
  6. var id = res.result.songs[0].id;

用id发送http请求获取imgUrl和音乐源

用id获取到imgUrl
image.png

用id获取到播放源
image.png