【前端学习笔记】AJAX、axios、fetch、跨域

1.介绍

AJAX(Asynchronous JavaScript and XML)异步的JS和XML。通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

XML 可扩展标记语言

  • XML 被设计用来传输和存储数据。
  • XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。
xml 复制代码
<student>
	<name>孙悟空</name>
	<age>18</age>
	<gender>男</gender>
</student>

现在已经被 JSON 取代

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

AJAX优点

  • 可以无需刷新页面而与服务器端进行通信
  • 允许你根据用户事件来更新部分页面内容

缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题(同源)
  • SEO(搜索引擎优化) 不友好

AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,能够更新部分网页的技术。虽然它提高了用户体验,但是它对搜索引擎优化(SEO)有不利影响,原因如下 :

  1. 搜索引擎爬虫无法执行JavaScript:AJAX通过JavaScript动态加载内容,而传统的搜索引擎爬虫无法执行JavaScript,因此无法抓取和索引这些动态生成的内容 。
  2. URL不变性 :使用AJAX的网站可能会使用井号(#)来表示不同的内容状态,如http://example.com#1http://example.com#2等。然而,搜索引擎通常不会抓取井号后面的内容,因为它们不认为这是一个新的URL或页面 。
  3. 内容延迟加载:AJAX通常用于延迟加载内容,这意味着当页面首次加载时,某些内容并不存在。搜索引擎爬虫可能在内容通过AJAX加载之前就已经抓取了页面,导致这些内容未被索引 。
  4. 缺乏元信息:AJAX加载的内容可能包括重要的元信息,如标题、描述和关键词,这些信息对于搜索引擎评估网页的相关性和质量至关重要。如果这些信息是通过AJAX加载的,搜索引擎可能无法获取它们 。
  5. 单页面应用(SPA)问题:许多现代网站采用单页面应用结构,整个网站只有一个URL,所有内容都通过AJAX动态加载。这使得搜索引擎难以区分不同的内容和页面,从而影响网站的SEO 。
    为了减少AJAX对SEO的不利影响,可以采取以下措施 :
  • 使用预渲染:在服务器端生成静态HTML页面,并将其返回给搜索引擎爬虫,这样即使搜索引擎无法解析JavaScript,也可以看到完整的页面内容 。
  • 使用History API:通过History API改变浏览器的URL,而不会导致页面重载,这样即使使用AJAX更新页面内容,也可以保持URL不变 。
  • 提供静态HTML副本:创建静态HTML副本供搜索引擎爬虫访问,确保搜索引擎能看到网站的完整内容并正确索引 。
  • 使用无干扰URL:确保在使用AJAX时,URL能反映正确的页面状态,这样搜索引擎爬虫可以通过访问不同的URL来获取不同页面状态的内容 。
  • 合理使用AJAX:仅在必要时使用AJAX,并确保合适的备用内容,以平衡用户体验与SEO的需求 。

2.HTTP

HTTP 超文本传输协议,HyperText Transfer Protocol,是一种用作获取诸如 HTML 文档这类资源的协议。它是 Web 上进行任何数据交换的基础,同时,也是一种客户端---服务器(client-server)协议,也就是说,请求是由接受方------通常是 Web 浏览器------发起的。完整网页文档通常由文本、布局描述、图片、视频、脚本等资源构成。

客户端与服务端之间通过交换一个个独立的消息 (而非数据流)进行通信。由客户端发出的消息被称作请求 (request),由服务端发出的应答消息被称作响应(response)。

HTTP 是一个客户端---服务器协议:请求由一个实体,即用户代理(user agent),或是一个可以代表它的代理方(proxy)发出。大多数情况下,这个用户代理都是一个 Web 浏览器,也可以是一个爬取网页来充实、维护搜索引擎索引的机器爬虫。

一般服务器与浏览器的交互过程是:

  1. 前后应用从浏览器端向服务器发送HTTP 请求(请求报文)
  2. 后台服务器接收到请求后,调度服务器应用处理请求,向浏览器端返回HTTP响应(响应报文)
  3. 浏览器端接收到响应,解析显示响应体/调用监视回调
HTTP的工作原理

HTTP 基于"请求-响应"范式,在客户端和服务器之间建立一个连接,客户端发送一个请求,服务器回复一个响应。这个过程通常涉及以下步骤:

  1. 客户端连接到服务器:客户端(通常是网络浏览器)通过URL连接到服务器。URL指定了所请求资源的位置。
  2. 发送HTTP请求:客户端向服务器发送一个HTTP请求消息,请求可以是获取文件、提交表单内容、下载数据等。
  3. 服务器处理请求并发送响应:服务器接收并解析请求,然后找到请求的资源,并发送一个HTTP响应消息。
  4. 释放连接或保持开启:在HTTP/1.0中,每个请求/响应对后连接通常被关闭。在HTTP/1.1中,持久连接成为默认方式,可以在同一连接上发送和接收多个请求/响应。
  5. 客户端显示响应:浏览器接收响应并根据需要渲染页面,例如显示HTML或其它错误消息。

HTTP通信由两种类型的消息组成:请求和响应,每种都有其特定格式。

HTTP请求

  • 请求行:包括方法(如GET、POST)、请求的URI和HTTP版本。
  • 请求头:包含了诸如 User-Agent、Accept-Type、Cookie 等一系列请求头,这些头提供了关于请求者和请求类型的额外信息。
  • 空行:请求头后面的空行是请求头和请求体的分隔符。
  • 请求体(可选):数据部分,不在GET方法中使用,但在POST方法中用来提交表单等数据。

HTTP响应

  • 状态行:包括HTTP版本、状态码(如200、404)和状态消息(如OK、Not Found)。
  • 响应头:包括 Content-Type、Content-Length、Set-Cookie 等,描述了响应的类型和行为。
  • 空行:响应头后面的空行是响应头和响应体的分隔符。
  • 响应体:服务器返回的实际数据。

HTTP定义了一系列请求方法,最常见的包括:

  • GET:请求获取指定的资源。
  • POST:提交数据给服务器(例如表单数据)。
  • PUT:将请求的数据存储在指定的URI(如果URI不存在,则创建它)。
  • DELETE:删除指定的资源。
  • HEAD:类似于GET,但只请求资源的头部信息。
  • OPTIONS:描述目标资源的通信选项。

状态码是服务器在响应头中返回的三位数字代码,它描述了请求的处理结果。常见的状态码包括:

  • 200 OK:请求成功。
  • 301 Moved Permanently:请求的资源已永久移动到新位置。
  • 400 Bad Request:服务器无法理解请求的格式。
  • 404 Not Found:请求的资源未找到。
  • 500 Internal Server Error:服务器内部错误。

HTTPS (全称 HyperText Transfer Protocol Secure)是 HTTP 的安全版本,两者的主要区别在于 HTTPS 在传输数据时提供了加密、身份验证和数据完整性的保障。这是通过使用安全套接层(SSL)或其继任者传输层安全(TLS)协议来实现的。

以下详细阐述 HTTP 和 HTTPS 的主要区别和特点:

  1. 安全性
    HTTP 是无加密的,传输的数据都是明文,这使得HTTP通信容易受到中间人攻击(MITM),攻击者可以轻松地截取、修改或重定向数据。
    HTTPS 在 HTTP 的基础上通过 TLS/SSL 加密通信通道,保护数据不被中间人窃听、篡改。即使数据被截获,加密保护也使得数据无法被读取。
  2. 端口
    HTTP 默认使用端口 80。
    HTTPS 默认使用端口 443。
  3. 性能
    HTTP 不涉及加密过程,因此在数据传输上更快。
    HTTPS 由于数据加密处理,会稍微消耗更多的计算资源,可能导致初次建立连接时有更多的延迟。然而,随着现代计算能力的提高和优化,这种性能差距已经大大减小。
  4. 成本
    HTTP 不需要额外的证书。
    HTTPS 需要为服务器获取和维护 SSL/TLS 证书,尽管许多组织如 Let's Encrypt 提供了免费证书,但大型企业可能需要购买高保证的证书,这带来了额外成本。
  5. URL前缀
    HTTP 的 URL 前缀是 http://。
    HTTPS 的 URL 前缀是 https://,这表明安全的连接。
  6. 隐私和完整性
    HTTP 不能确保数据在传输过程中的隐私和完整性。
    HTTPS 通过加密保证了数据的隐私性,通过完整性校验确保数据在传输过程中未被修改。
  7. 搜索引擎优化(SEO)
    使用 HTTPS 可以是一个轻微的搜索排名提升因素,因为 Google 确认 HTTPS 是搜索引擎优化的一个正面指标。
  8. SEO影响
    从 HTTP 切换到 HTTPS 可提高网站的可信度,同时对 SEO 有正面影响。

3.AJAX

AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容的技术。AJAX 的核心在于 XMLHttpRequest 对象,尽管它的名字中包含 XML,但它可以处理任何格式的数据,包括文本、HTML、JSON 等。

AJAX 的操作通常涉及以下步骤:

  1. 创建 XMLHttpRequest 对象:XMLHttpRequest(XHR)对象是实现 AJAX 的主要技术手段。虽然名字中包含 XML,XHR 对象可以用来处理任何格式的数据,包括纯文本、HTML、JSON 等。
  2. 发送请求到服务器:使用 XMLHttpRequest 发送请求。可以指定请求的类型(GET、POST 等)、URL、是否异步执行、用户认证信息等。
  3. 服务器处理请求:服务器接收到请求后,根据请求内容处理请求,并准备响应。
  4. 发送响应到客户端:服务器将数据发送回客户端。这些数据可能是更新后的 HTML、纯文本、JSON 或 XML 等。
  5. 处理服务器响应:客户端的 XMLHttpRequest 对象接收到数据后,JavaScript 会处理这些数据,如解析 JSON 数据,并更新网页的相应部分。

语法:

  1. 创建XMLHttpRequest对象
javascript 复制代码
var xhr = new XMLHttpRequest();
  1. 配置 XMLHttpRequest 请求:使用 .open() 方法配置请求。这个方法需要几个参数:请求的方法("GET" 或 "POST"),URL(请求的服务器地址和数据资源),以及一个布尔值指明请求是否异步处理。
javascript 复制代码
xhr.open('GET', 'https://api.example.com/data', true);
  1. 发送请求:调用 .send() 方法发送请求。如果是一个 "GET" 请求,传递 null 作为参数;如果是 "POST" 请求,传递要发送的数据。
javascript 复制代码
xhr.send();
// 对于post请求
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify({key: "value"}));
  1. 处理服务器响应:使用 onreadystatechange 事件处理器来处理响应,这个处理器会在 XMLHttpRequest 的 readyState 属性改变时被调用。readyState 的值为 4 表示请求已完成,且响应已就绪。
javascript 复制代码
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) { // 请求已完成,响应已就绪
        if (xhr.status === 200) { // HTTP状态 200: OK
            console.log(xhr.responseText); // 打印响应的内容
        } else {
            console.error("Request failed: " + xhr.status); // 打印错误状态
        }
    }
};
  1. 更新页面内容:一旦你从服务器接收到数据,你可以根据获取的数据来更新网页内容。假设响应的内容是 JSON 格式,你可以解析这个 JSON 并使用数据来动态更新 DOM。
javascript 复制代码
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var data = JSON.parse(xhr.responseText); // 解析 JSON 数据
        document.getElementById('someElement').innerHTML = data.content; // 更新DOM
    }
};

API

xhr.readyState 可以用来查看请求当前的状态:

4.axios

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 node.js。它提供了一种简单的方式来发送各种 HTTP 请求,并处理响应。Axios 的流行部分原因是它具备丰富的配置选项和拦截请求与响应的能力,还包括自动转换 JSON 数据的功能和客户端支持防御 XSRF 的安全特性。

默认使用方式:

默认使用get方式发送无参请求:

javascript 复制代码
axios({
	url:'https://api'
}).then(res=>{})

指定方式发送无参请求:

javascript 复制代码
axios({
	url:'https://api',
	method:'get'
}).then(res=>{})

axios({
	url:'https://api',
	method:'post'
}).then(res=>{})

get 发送有参请求:

javascript 复制代码
// 查询字符串
axios({
	url:'https://api?key=value',
	method:'get'
}).then(res=>{})

axios({
	url:'https://api',
	params:{
		key:'value',
	},
	method:'get'
}).then(res=>{})

post 发送有参请求:

javascript 复制代码
axios({
	url:'https://api',
	params:{
		key:'value',
	},
	method:'post'
}).then(res=>{})

axios({
	url:'https://api',
	data:{
		key:'value',
	},
	method:'post'
}).then(res=>{})

一般post发送参数都是用data,但是data会将这些数据作为请求体发送。这个 data 可以是任何 JavaScript 对象,Axios 会将其转换为 JSON 字符串,除非你指定了其他的 Content-Type。

为了方便,还设置了别名函数。

get无参:

javascript 复制代码
axios.get('url').then(res=>{}).catch(err=>{})

get有参:

javascript 复制代码
axios.get('url',{parmas:{key:'value'}}).then(res=>{}).catch(err=>{})

post无参:

javascript 复制代码
axios.post('url').then(res=>{}).catch(err=>{})

post有参:

javascript 复制代码
axios.post('url',"key=value&key2=value2").then(res=>{}).catch(err=>{})

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

并发

javascript 复制代码
axios.all([
	axios.get('url'),
	axios.post('url')])
.then(
	axios.spread((res1,res2)=>{})
).catch(err=>{})

全局默认配置:

javascript 复制代码
axios.defaults.baseURL='';
axios.defaults.timeout=2000;

实例

javascript 复制代码
let newVar=axios.create({
	baseURL:'',
	timeout:5000
});
newVar({
	url:''
}).then(res=>{})

拦截器

在发起请求或响应对操作进行处理,被 then 或 catch 处理前拦截它们。约等于过滤器。

axios两大类拦截器:请求方向的拦截 响应方向拦截。

javascript 复制代码
// 添加请求拦截器
axios.interceptors.request.use(config=>{
    // 在发送请求之前做些什么
    return config;
  }, error=>{
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(response=>{
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, error=>{
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });

移除拦截器:

javascript 复制代码
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

响应结构:

javascript 复制代码
{
  // `data` 由服务器提供的响应
  data: {},

  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: 'OK',

  // `headers` 是服务器响应头
  // 所有的 header 名称都是小写,而且可以使用方括号语法访问
  // 例如: `response.headers['content-type']`
  headers: {},

  // `config` 是 `axios` 请求的配置信息
  config: {},

  // `request` 是生成此响应的请求
  // 在node.js中它是最后一个ClientRequest实例 (in redirects),
  // 在浏览器中则是 XMLHttpRequest 实例
  request: {}
}

5.fetch API

fetch API,它提供了一种更现代、更强大、基于 Promise 的接口来处理 AJAX 请求。fetch API 最基本的用法只需要向 fetch() 函数传递一个 URL 字符串。Fetch 提供了对 Request 和 Response(以及其他与网络请求有关的)对象的通用定义。

发送请求

javascript 复制代码
fetch('https://api.example.com/data', {
  method: 'POST', // 指定请求方法
  headers: {
    'Content-Type': 'application/json' // 设置请求头
  },
  body: JSON.stringify({ key: 'value' }) // 设置请求体
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

错误处理:fetch 只有在网络错误发生时(如请求无法发出)才会拒绝(reject)Promise。如果 HTTP 请求返回了错误状态码(如 404 或 500),fetch 仍会解析为一个成功的 Promise。因此,检查响应的状态码是必要的:

javascript 复制代码
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) { // 如果响应状态码不是 2xx
      throw new Error('Network response was not ok ' + response.statusText);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

fetch 还支持信号和控制器(AbortController),用于取消正在进行的请求:

javascript 复制代码
const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
    } else {
      console.error('Fetch error:', error);
    }
  });

// 取消 fetch
controller.abort();

响应:

6.跨域

同源策略 (Same-Origin Policy)最早由Netscape 公司提出,是浏览器的一种安全策略。同源:协议域名端口号必须完全相同。

同源策略主要限制以下几种行为:

  • 通过 document 对象访问另一个源的 DOM。
  • 从另一个源的网页中获取 localStorage 或 cookies。
  • 跨源 XMLHttpRequest 或 fetch 请求。

跨域(Cross-Origin)是指当一个网页尝试访问与自己不同源的资源时的情况。由于同源策略的限制,跨域请求默认是被阻止的,除非目标服务器明确允许这种访问。

为了解决跨域问题,可以采用以下几种方法:

  • CORS(跨源资源共享):服务器通过设置特定的HTTP头部(如 Access-Control-Allow-Origin)来允许特定的外部域访问其资源。
  • JSONP(已逐渐被CORS取代):通过 <script> 标签获取跨域数据,但只支持GET请求。(img link iframe script 这些标签本身就支持跨域。)
  • 代理服务器:在同源的服务器上设置代理,由代理服务器请求跨域资源,然后转发给客户端。


参考

[1] HTTP

[2] AJAX

[3] 跨域问题

相关推荐
木子七6 分钟前
vue3-setup中使用响应式
前端·vue
廖子默16 分钟前
提供html2canvas+jsPDF将HTML页面以A4纸方式导出为PDF后,内容分页时存在截断的解决思路
前端·pdf·html
Moment18 分钟前
毕业半年,终于拥有了两个近 500 star 的开源项目了 🤭🤭🤭
前端·后端·开源
ps酷教程25 分钟前
webrtc视频会议学习(三)
学习·webrtc
楚疏笃41 分钟前
鸿蒙学习自由流转与分布式运行环境-跨端迁移(2)
分布式·学习·harmonyos
光影少年1 小时前
react和vue图片懒加载及实现原理
前端·vue.js·react.js
AndyGoWei1 小时前
react react-router-dom history 实现原理,看这篇就够了
前端·javascript·react.js
小仓桑1 小时前
深入理解 JavaScript 中的 AbortController
前端·javascript
澜世1 小时前
2024小迪安全基础入门第七课
网络·笔记·安全·网络安全