一、Ajax
Ajax:(也写为AJAX 读作/ˈeɪdʒæks/或阿贾克斯. “Asynchronous JavaScript and XML”(异步JavaScript和XML)的缩写)是一组Web开发技术,Ajax不是一种技术,而是一个编程概念。AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。
技术实现
- 用于演示的HTML(或 XHTML)和 CSS
- 文档对象模型(DOM),用于动态显示数据并与之交互
- 用于数据交换的 JSON 或 XML,以及用于 XML 操作的 XSLT
- 用于异步通信的XMLHttpRequest对象
- 将这些技术结合在一起的JavaScript
原生javascript示例
GET 方法
使用 GET 方法的简单 Ajax 请求的示例,用JavaScript编写.
// 这是客户端脚本.// 初始化HTTP请求.let xhr = new XMLHttpRequest();// 定义请求xhr.open('GET', 'send-ajax-data.php',true);//true表示异步,false表示同步,默认为 true,指示是否异步执行操作。// 跟踪请求的状态更改.xhr.onreadystatechange = function () {const DONE = 4; // readyState 4 表示请求已完成.const OK = 200; // 状态 200 是一个成功返回.if (xhr.readyState === DONE) {if (xhr.status === OK) {console.log(xhr.responseText); // '这是输出.'} else {console.log('Error: ' + xhr.status); // 请求期间出错.}}};//发送发送到 send-ajax-data.phpxhr.send(null);
POST方法
使用 POST 方法的简单 Ajax 请求的示例,用JavaScript编写.
const xhr = new XMLHttpRequest();xhr.open("POST", 'send-ajax-data2.php', true);//随请求一起发送正确的标头信息xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xhr.onreadystatechange = () => { // 在状态更改时调用函数.if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {// 请求已完成。在这里进行处理.console.log(xhr.responseText); // '这是输出.'}}xhr.send("foo=bar&lorem=ipsum");// xhr.send(new Int8Array());// xhr.send(document);
JQUERY方法示例
GET方法
$.get("send-ajax-data.php",function(data){console.log(data);});$.get("send-ajax-data.php", { name: "John", time: "2pm" } ,function(data){console.log(data);});或:$.ajax({type: 'GET',url: 'send-ajax-data.php',data: { name: "John", time: "2pm" } ,//url请求参数:可选success: function (resp) {console.log(resp);},error: function () {}});
GET JSON方法
//只能接受json格式的数据$.getJSON('send-ajax-data2.php', function (data) {console.log(data);});
POST JSON方法
$.post("test.php", { name: "John", time: "2pm" },function(data){console.log(data.name); // Johnconsole.log(data.time); //2pm}, "json");或:var data = {"name": "Ajax中文网","url": "http://ajax.p2hp.com/"};$.ajax({type: 'POST',url: 'send-ajax-data3.php',data: data,dataType: "json",//dataType:"jsonp",//jsonp是跨域方式async: true,//是否异步(ajax默认是异步的)success: function (resp) {console.log(resp);}, error: function () {}});
二、Fetch(代替品)
Fetch是一个新的原生JavaScript API。 根据谷歌开发者文档,“Fetch使得发出网络请求和处理响应比使用旧的XMLHttpRequest更容易.
GET方法
ES6(Promise)
fetch('send-ajax-data.php') .then(response => response.json()) .then(json => console.log(json)) .catch(err => console.log('Request Failed', err));
fetch('/mock/xxxxx').then(res => {console.log(res)//是一个综合各种方法的对象,并不是请求的数据 和axios的区别(fetch的返回值是一个promise对象) if(res.ok){ res.json().then(data=>{ console.log(data)//json数据和axios的区别 }) }}).catch(err => {console.log(err)})
ES7(async/await)
async function doAjax1() {try {const res = await fetch('send-ajax-data2.php');if (!res.ok) {}//const data = await res.text();const data = await res.json();console.log(data);} catch (error) {console.log('Error:' + error);}}doAjax1();
POST方法
async function doAjax1() {try {var data = {name: 'John',age: 30};const res = await fetch('send-ajax-data2.php', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)});if (!res.ok) {}//const dataresp = await res.text();const dataresp = await res.json();console.log(dataresp);} catch (error) {console.log('Error:' + error);}}doAjax1();
const arr1 = [{name: "haha",detail:"123"}];fetch("url", {method: "post",credentials: "include",//默认为omit,忽略的意思,//也就是不带cookie还有两个参数,same-origin,//意思就是同源请求带cookie;include,表示无论跨域还是同源请求都会带cookieheaders: {//设置请求的头部信息 ""Content-Type": "application/json", "Accept":"allication/json",} //将arr1对象序列化成json字符串 body: JSON.stringify(arr1)//向服务端传入json数据}).then(res) {console.log(res)//是一个综合各种方法的对象,并不是请求的数据 和axios的区别 if(res.ok){ res.json().then(data=>{ console.log(data) //json数据和axios的区别 }) }}).catch(err => { console.log(err)})
总结
典型的 fetch 请求由两个await
调用组成:
let response = await fetch(url, options); // 解析 response headerlet result = await response.json(); // 将 body 读取为 json
或者以 promise 形式:
fetch(url, options).then(response => response.json()).then(result => /* process result */)
Fetch依赖于JavaScript promises。
Fetch规范在以下几个方面与 Ajax 不同:
从 fetch()返回的Promise不会在 HTTP 错误状态下拒绝,即使响应是 HTTP 404 或 500。相反,一旦服务器使用标头进行响应,Promise 就会正常解析(如果响应不在 200–299 范围内,则响应的 ok 属性设置为 false),并且只有在网络出现故障或有任何阻止请求完成时才会拒绝。 fetch()不会发送跨域 Cookie,除非您设置了凭据初始化选项(credentials init option)。
fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。
注意:fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
三、Axios
Axios 是一个基于promise网络请求库,作用于node.js和浏览器中。 它是isomorphic的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.jshttp
模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
执行GET
请求
// 为给定 ID 的 user 创建请求axios.get('/user?ID=12345').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});// 上面的请求也可以这样做axios.get('/user', {params: {ID: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
执行POST
请求
axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
执行多个并发请求
function getUserAccount() {return axios.get('/user/12345');}function getUserPermissions() {return axios.get('/user/12345/permissions');}axios.all([getUserAccount(), getUserPermissions()]).then(axios.spread(function (acct, perms) {// 两个请求现在都执行完成}));
或者以形式处理多个请求
在 Axios 中,可以使用axios.all和axios.spread来处理多个并发的请求:
const axios = require('axios');// 创建多个请求const request1 = axios.get('https://api.example.com/data1');const request2 = axios.get('https://api.example.com/data2');// 并发发送多个请求axios.all([request1, request2]).then(axios.spread((response1, response2) => {// 处理各个请求的响应console.log(response1.data);console.log(response2.data);})).catch(error => {// 处理错误console.error(error);});
可以看到,在.then方法中使用了axios.spread函数将多个请求的响应结果进行解构,通过多个参数分别接收各个请求的响应。可以根据实际情况命名这些参数,并通过response1.data、response2.data等方式获取各个请求的响应数据。
请求拦截、响应拦截
在 Axios 中,可以使用transformRequest方法在请求发送之前对请求数据进行转换和处理,它是一个请求拦截器,是一个可选的函数。
transformRequest函数接收两个参数:requestData和requestHeaders。其中,requestData是要发送的请求数据,requestHeaders是要发送的请求头信息。可以在transformRequest函数内部对这些参数进行修改,并将修改后的值返回。返回的结果将作为实际发送请求的数据。
axios({url: 'https://api.example.com/data',method: 'post',data: {id: 12345,name: 'John Doe'},transformRequest: (data, headers) => {// 对请求数据进行转换和处理const modifiedData = { ...data }; // 复制原始数据// 修改数据或添加额外字段modifiedData.extraField = 'Extra Value';// 修改请求头信息headers['Content-Type'] = 'application/json';return JSON.stringify(modifiedData); // 返回处理后的数据}}).then(response => {// 处理成功响应console.log(response.data);}).catch(error => {// 处理错误console.error(error);});
这里使用 Axios 发起了一个 POST 请求。通过传递包含transformRequest函数的配置对象来定义请求。在transformRequest函数内部,复制了原始的请求数据data,并进行了一些修改和处理,如添加了额外的字段和修改了请求头信息。最终,将修改后的数据以 JSON 字符串的形式返回。Axios 将使用transformRequest函数返回的结果作为实际发送请求的数据。
除了可以对请求进行拦截之外,Axios 还支持对响应进行拦截,对响应数据进行转换和处理。可以通过transformResponse响应拦截器来实现。该函数接收一个参数:responseData,它是从服务器接收到的原始响应数据。可以在transformResponse函数内部对这个参数进行修改,并将修改后的值返回。返回的结果将作为实际处理响应的数据。
axios.get('https://api.example.com/data', {transformResponse: (data) => {// 对响应数据进行转换和处理const parsedData = JSON.parse(data); // 解析 JSON 字符串// 修改数据或添加额外字段parsedData.extraField = 'Extra Value';return parsedData; // 返回处理后的数据}}).then(response => {// 处理成功响应console.log(response.data);}).catch(error => {// 处理错误console.error(error);});
这里使用 Axios 发起了一个 GET 请求,并通过传递包含transformResponse函数的配置对象来定义请求。在transformResponse函数内部,对从服务器接收到的响应数据data进行了一些修改和处理,如解析 JSON 字符串,添加了额外的字段。最终将修改后的数据返回。
拦截请求和响应
Axios 中,可以使用拦截器来拦截请求和响应,并在其被发送或接收之前进行一些额外的处理,可以通过axios.interceptors对象来添加拦截器。
// 添加请求拦截器axios.interceptors.request.use(config => {// 在发送请求之前做一些处理console.log('请求拦截器');// 修改请求配置config.headers['Authorization'] = 'Bearer token';return config;}, error => {// 处理请求错误console.error('请求出错:', error);});// 添加响应拦截器axios.interceptors.response.use(response => {// 在接收到响应数据之前做一些处理console.log('响应拦截器');// 修改响应数据response.data = { ...response.data, extraField: 'Extra Value' };return response;}, error => {// 处理响应错误console.error('响应出错:', error);});// 发送请求axios.get('https://api.example.com/data').then(response => {// 处理成功响应console.log(response.data);}).catch(error => {// 处理请求或响应错误console.error(error);});
这里首先使用axios.interceptors.request.use方法添加了一个请求拦截器。该拦截器在发送请求之前被调用,并接收请求配置对象config作为参数。可以对请求配置进行修改,如添加请求头信息。最后,要确保返回修改后的配置对象。
接下来,使用axios.interceptors.response.use方法添加了一个响应拦截器。该拦截器在接收到响应数据之前被调用,并接收响应对象response作为参数。可以对响应数据进行修改,如添加额外的字段。同样,要确保返回修改后的响应对象。
取消请求
在 Axios 中,可以使用取消令牌(cancel token)来取消请求。取消令牌是一个对象,它表示一个具体的取消操作,并允许在需要时中止请求。
// 创建一个取消令牌源const CancelToken = axios.CancelToken;const source = CancelToken.source();// 发送请求axios.get('/api/data', {cancelToken: source.token}).then(response => {console.log(response.data);}).catch(error => {if (axios.isCancel(error)) {console.log('请求已被取消:', error.message);} else {console.error(error);}});// 取消请求source.cancel('取消请求的原因');
这里,先创建了一个取消令牌源source。然后,发送 GET 请求时将cancelToken配置选项设置为source.token,即将取消令牌与该请求关联起来。当需要取消请求时,调用source.cancel()方法,并传入取消请求的原因作为参数。
在请求的.catch()方法中,我们使用axios.isCancel(error)来判断捕获的错误是否是一个已取消的请求。如果是取消请求导致的错误,则会打印出 ‘请求已被取消’ 的提示信息。否则,将打印出其他类型的错误。
请求超时
可以使用timeout配置选项设置 Axios 请求的超时时间,这个选项指定了请求在多少毫秒后如果没有得到响应就会超时。
axios.get('/api/data', {timeout: 5000 // 设置超时时间为5秒}).then(response => {console.log(response.data);}).catch(error => {console.error(error);});
发送了一个 GET 请求,并在配置选项中设置了timeout为 5000 毫秒(即 5 秒)。如果请求在 5 秒内没有得到响应,就会触发超时错误。在超时错误的情况下,请求会被自动取消,并且进入.catch()分支。您可以根据需要进行错误处理。
注意,如果不设置timeout选项,默认情况下 Axios 请求是没有超时限制的。
axios和fetch的区别
axios("http://xxx/xxx.json?a=123'").then((res)=>{ console.log(res)//这里的res是响应结果})
fetch("http://www.baidu.com").then((res)=>{ console.log(res);//是一个综合各种方法的对象(fetch的返回值是一个promise对象),并不是请求的数据//还需要res.json().then(data=>{}})
axios :
- 从浏览器中创建 XMLHttpRequest
- 从 node.js 发出 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 自动转换JSON数据
- 客户端支持防止CSRF/XSRF
fetch:
符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里, 更加底层,提供的API丰富(request, response),脱离了XHR,是ES规范里新的实现方式
- fetchtch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
- fetch默认不会带cookie,需要添加配置项
- fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费
- fetch没有办法原生监测请求的进度,而XHR可以
- fetch的返回值是一个promise对象
ajax和fetch的区别 :
- ajax是理用XMLHttpRequest对象来请求数据的,而fetch是window的一个方法
- ajax基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
- fetch比较与ajax有着更好更方便的写法
- fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
- fetch没有办法原生监测请求的进度,而XHR可以
四、Get
GET请求通常用于从服务器请求数据。例如,当你在浏览器中输入一个网址并按Enter键时,你实际上发送了一个GET请求来获取网页的内容。
// 发起GET请求fetch('https://api.example.com/data').then(response => response.json()).then(data => console.log(data)).catch(error => console.error('Error:', error));
五、Post
POST请求通常用于提交数据到服务器。例如,当你在网页上填写一个表单并提交时,你实际上发送了一个POST请求来发送表单数据。
// 要提交的数据const data = {username: 'john_doe',password: 'secret123'};// 发起POST请求fetch('https://api.example.com/login', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)}).then(response => response.json()).then(data => console.log(data)).catch(error => console.error('Error:', error));
get与post区别
GET和POST请求在HTTP协议中用于向服务器发送数据,但它们在使用方式、数据传输和安全性等方面存在一些重要的区别。
- 数据传输方式:GET请求的数据会被附加在URL之后,而POST请求的数据则包含在请求体中。这意味着GET请求的数据会显示在浏览器地址栏中,而POST请求的数据则不会。
- 数据量限制:由于GET请求的数据附加在URL中,因此对数据量有一定的限制,这取决于浏览器和代理的设置。而POST请求没有这种限制,可以发送大量数据。
- 安全性:由于GET请求的数据在URL中传输,因此不太安全,不适合传输敏感数据或大量数据。而POST请求的数据在请求体中传输,相对更安全。
- 缓存机制:GET请求可以被浏览器缓存,而POST请求则不能。
- 目的:GET请求主要用于从服务器获取数据,而POST请求主要用于向服务器提交数据。
- 参数传递:GET请求的参数在URL中传递,而POST请求的参数在请求体中传递。
- 效率:由于GET请求可以直接从浏览器地址栏中输入,并且支持刷新和后退操作,因此执行效率较高。而POST请求不支持刷新和后退操作,需要重新发送数据。
简单来说,get 和post 是 HTTP 请求中最常用的两种请求方法。get是用来获取数据,post是用来提交数据。get 在url?问号后面携带参数,不安全;post通常在请求体内携带参数,相对get安全些。get具有缓存功能 ,post没有缓存功能。