入门魔法 - AJAX

前情提要

经过上次火属性初阶魔法近距离灼伤手指後。

「就不能让这个火离我远一点吗?远距离魔法不存在吗?」

艾草:「你这麽一说我倒是想起来了,有一个方法可以远距离施放。」

「这麽重要的事情不能早点说嘛!」

艾草:「嗯,可以透过你去请求空气中的精灵,而精灵依请求回应你。」

「听起来很厉害,快点开始吧!」

艾草:「好,那先跟着我学习远距离魔法 AJAX 原理吧!」

https://ithelp.ithome.com.tw/upload/images/20210930/20139066y73YZcNheL.png

(虽然跟精灵的沟通也是常有问题啦 ( ´Д`)y━・~~)


AJAX

AJAX 全名为「Asynchronous JavaScript and XML」是一种 JavaScript 非同步执行的技术,可以拿来解决 Web 更新资料时,每次都要重新载入页面的困扰,透过只更新该页面需求资料,增加使用者体验。

在讲解 AJAX 方法前,先简单了解一下网路请求 Request 、 网路回应 Response 吧!

透过搜寻引擎打开网页时,网页到底都做了些什麽呢?

浏览器会替我们发出网路请求 Request 到服务器,而对方服务器会透过 Response 回应我们的请求!

https://ithelp.ithome.com.tw/upload/images/20210930/20139066aaLBYiizYx.png

如何透过浏览器查看该过程呢?

以下以 Google Chrome 浏览器为示范:

https://ithelp.ithome.com.tw/upload/images/20210930/20139066XlupwhFLyC.png

接着透过点击想查看的档案,能看到里面会记载详细的 Request 、Response 资讯,通常 Request 会夹带个人资讯在 Request Headers 让对方服务器认识你,当对方服务器认识完你後会 Response 你要的资料 。

https://ithelp.ithome.com.tw/upload/images/20210930/20139066GxkpPchPJg.png

当然不只可以透过网址来发送网页请求,也可以透过写 JavaScript 来发送网路请求,这就要仰赖我们的 AJAX 啦。


AJAX 原生方法

原生方法有两种分别为 XMLHttpRequestFetch ,我们将分别介绍此两种写法:

XMLHttpRequest

此方法为最传统的方法,是透过建立一个 XHR 物件,输入网址後送出网路请求,在透过设定好的回传函式接收服务器传回来的 Response 回应,此种方法写法会较为冗长,范例如下:

//产生 XMLHttpRequest() 
let xhr = new XMLHttpRequest();

//连结想捞取资料的页面
//带入三个参数
//1.格式(get、post 等)、2.要捞资料的网址、3.同步非同步(布林)
xhr.open('get', 'XMLHttpRequest-sample', true);

//发送请求过去,参数可带入想 post 过去的资料
xhr.send(null);

//拿到资料後,依据成功与否到对应函式内处理
xhr.onload = function () {
    //传回来的字串转成物件格式
    const data = JSON.parse(xhr.responseText);
    console.log(data);
};
xhr.onerror = function (err) {
  console.log('错误', err)
};

Fetch

Fetch 程序码相比 XMLHttpRequest 简洁很多,但因为是较新的语法,可能要留意浏览器的支援程度,Fetch 的写法如下:

//带入要发送请求的网址,与格式(get、post 等)
fetch('Fetch-sample', {method: 'get'})
		.then(function (response) {
        //需将回传资料透过 .json() 先处理过
        return response.json()
    }).then(function (data) {
        //等待对方回传资料後执行
        console.log(data)//印出回传结果
    })

非同步

来透过 XMLHttpRequest 了解非同步观念,在预设非同步的状况下,两次资料分别会印出什麽?执行顺序又是什麽呢?

//高雄 open data API 网址
const api = 'https://data.kcg.gov.tw/dataset/6f29f6f4-2549-4473-aa90-bf60d10895dc/resource/30dfc2cf-17b5-4a40-8bb7-c511ea166bd3/download/lightrailtraffic.json';

let xhr = new XMLHttpRequest();
xhr.open('get', api, true);
xhr.send(null);
xhr.onload = function () {
    const data = JSON.parse(xhr.responseText);
    console.log(1, data);//?
};
console.log(2, xhr.responseText);//?

透过结果会发现下方第二个 console.log() 反而印出的比第一个快,而且根本没有取到值,那便是因为非同步!

显示结果:
https://ithelp.ithome.com.tw/upload/images/20210930/20139066XYC5mevuZf.png

非同步概念指得是,当我们执行 AJAX 发送网路请求後,对方服务器尚未回传资料时, JavaScript 会先继续往下执行程序码,等到资料回传後才会去执行接收资料的函式。

总结

  • 浏览器会替我们发送网路请求 Request 给服务器、而服务器会网路回应 Response 浏览器
  • 可透过 Network 查看 Request HeadersResponse Headers 详细资讯
  • AJAX 原生方法有两种:XMLHttpRequest、Fetch
  • XMLHttpRequest 是最传统的方法,浏览器支援度也比较高
  • Fetch 是较新的方法,要留意浏览器支援度
  • AJAX 非同步:我们执行 AJAX 发送网路请求後,对方服务器尚未回传资料时, JavaScript 会先继续往下执行程序码,等到资料回传後才会去执行接收资料的函式。

了解完原生的方法後,下一篇文章让我们来聊聊如何使用 axios 套件发出网路请求吧!


小练习

请问以下叙述何者错误?
A AJAX 是一种同步 JavaScript 技术
B 浏览器发送 request 给服务器,服务器会网路回应 response 给浏览器
C XMLHttpRequest 发送网路请求会先建立一个 XHR 物件
D Fetch 语法较新,程序码也比 XMLHttpRequest 简洁很多

解答:选项 A 错误, 应该改成 AJAX 是一种同步 JavaScript 技术


参考文献

JavaScript 入门篇 - 学徒的试炼(六角学院)
JavaScript 必修篇 - 前端修练全攻略(六角学院)
https://wcc723.github.io/javascript/2017/12/28/javascript-fetch/
https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/ajax_fetch.html


<<:  Day 17:图与演算法

>>:  Day_18 NetData

【PHP Telegram Bot】Day30 - 社群按赞机器人(2):将按钮设成单选并且计数

阵列的特性 还记得阵列怎麽赋值吗,Day15 - 基础(4):阵列处理、JSON 我们先来复习一下...

EP 32: TopStore App with .NET Multi-platform App UI (MAUI)

Hello, 各位 iT邦帮忙 的粉丝们大家好~~~ 本篇是 Re: 从零开始用 Xamarin 技...

统一状态管理 + 单一资料流

我一开始在学 Vuex 的时候,觉得很难懂,不知道它是在做什麽的。当时的我,就想先追朔单一资料流的始...

4套最佳 Instagram 影片下载器-PC端〖2022亲测〗

作为最受欢迎的社交媒体平台之一,Instagram 绝对是在线分享媒体的最佳场所,例如照片、视频、直...

Day30:附魔

Annotation,大概最常见的就是@Override了,当我们写的类别继承自其他类别时,要覆写父...