文章目录

  • 1 Ajax 概述
    • 1.1 AJAX 简介
    • 1.2 XML 简介
    • 1.3 AJAX 的特点
      • 1.3.1 AJAX 的优点
      • 1.3.2 AJAX 的缺点
    • 1.4 AJAX 属性和方法
  • 2. HTTP相关问题
    • 2.1 MDN 文档
    • 2.2 HTTP 请求交互的基本过程
    • 2.3 HTTP 请求报文
    • 2.4 HTTP 响应报文
    • 2.5 post 请求体参数格式
    • 2.6 响应状态码
    • 2.7 不同类型的请求及其作用
    • 2.8 API 的分类
    • 2.9 区别:一般 http 请求与 ajax 请求
  • 3 原生 AJAX 的基本使用 XHR
    • 3.0 准备工作
      • 3.0.1 安装 node.js
      • 3.0.2 安装 express(服务端框架)
      • 3.0.3 安装 nodemon 自动重启工具
    • 3.1 理解
    • 3.2 核心对象使用步骤
      • 3.2.1 创建 XMLHttpRequest 对象
      • 3.2.2 设置请求信息(请求方法和url)
      • 3.2.3 发送请求
      • 3.2.4 接收响应(事件绑定,处理服务端返回的结果)
    • 3.3 GET 请求
    • 3.4 POST 请求
    • 3.5 设置请求头信息
    • 3.6 JSON 数据请求
    • 3.7 IE 缓存问题
    • 3.8 请求超时与网络异常
    • 3.9 取消请求
    • 3.10 请求重复发送问题
  • 4 jQuery 发送请求
    • 4.1 get 请求
    • 4.2 post 请求
  • 5 Axios 发送请求
  • 6 fetch 发送请求
  • 7 跨域
    • 7.1 同源策略
    • 7.2 JSONP
      • 7.2.1 原理
      • 7.2.2 JSONP 实践
      • 7.2.3 jQuery 中的 JSONP
    • 7.3 CORS
  • 8 完整的 server.js 代码

PS:服务器端完整代码 server.js 附在文章末尾
学习视频地址:https://www.bilibili.com/video/BV1WC4y1b78y?p=1

1 Ajax 概述

1.1 AJAX 简介

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

1.2 XML 简介

  • XML 可扩展标记语言
  • XML 被设计用来传输和存储数据
  • XMLHTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据

比如说我有一个学生数据:

​ name = “孙悟空” ; age = 18 ; gender = “男” ;

​ 用XML 表示:

<student><name>孙悟空</name><age>18</age><gender></gender>
</student>

​ 现在已经被JSON 取代了

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

1.3 AJAX 的特点

1.3.1 AJAX 的优点

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

1.3.2 AJAX 的缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题(同源)
  • SEO 不友好
    • 爬虫爬不到信息

1.4 AJAX 属性和方法

属性 描述
onreadystatechange 状态改变的事件触发器
readyState 对象状态(integer),状态值
0 = 未初始化,未调用send()方法
1 = 读取中,已调用send(),正在发送请求
2 = 已读取,send方法执行完成,接收到全部响应内容
3 = 交互中,正在解析响应内容
4 = 完成,响应内容解析完成
responseText 获得字符串形式的响应数据
responseXML 获得XML形式的响应数据
status 服务器返回的状态码,如:
404 = “文件未找到”
200 = “成功”
500 = “服务器内部错误”
304=“资源未被修改”
statusText 服务器返回的状态文本信息
timeout 指定请求超时时间,默认为 0 代表没有限制
ontimeout 绑定超时的监听
onerror 绑定请求网络错误的监听
方法 描述
abort() 停止当前请求
getResponseHeaders(“headerLabel”) 返回值指定响应首部(响应头)的串值
open(“method”, “url”, true) 建立对服务器的调用,method参数可以是GET、POST或PUT
url参数可以是相对URL或绝对URL 这个方法还包括3个可选参数
send(content) 向服务器发送请求
getAllResponseHeaders() 把 http 请求的所有响应首部(响应头)作为键/值对返回
setRequestHeader(“label”, “value”) 把指定首部设置为所提供的值 在设置任何首部之前必须先调用open()

2. HTTP相关问题

2.1 MDN 文档

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview

2.2 HTTP 请求交互的基本过程

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

2.3 HTTP 请求报文

  • 请求行 method url路径 http协议版本/1.1

    • GET /s?ie=utf-8 HTTP
    • POST /login
  • 请求头 键名: 键值

    • Host: www.baidu.com
    • Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3B0FA706;
    • Content-Type: application/x-www-form-urlencoded 或者 application/json
    • User-Agent: chrome 83
  • 空行,必须有

  • 请求体

    • GET 请求体为空

    • POST 请求体可以不为空

    • username=tom&pwd=123

    • {"username": "tom", "pwd": 123}

GET 的请求报文

POST 的请求报文

2.4 HTTP 响应报文

  • 响应状态行 HTTP协议版本 响应状态码 响应状态字符串(不需要单独设置)

    • HTTP/1.1 200 OK
    • 常见的状态响应码:
      • 200 OK 请求成功。一般用于GET 与POST 请求
      • 201 Created 已创建。成功请求并创建了新的资源
      • 401 Unauthorized 未授权/请求要求用户的身份认证
      • 404 Not Found 服务器无法根据客户端的请求找到资源
      • 500 Internal Server Error 服务器内部错误,无法完成请求
  • 2、响应头

    • Content-Type: text/html;charset=utf-8
    • Content-Length: 2048
    • Content-encoding: gzip
    • Set-Cookie: BD_CK_SAM=1;path=/
  • 空行,必须有

  • 响应体,html 标签里的全部内容

    • html 文本/json 文本/js/css/图片...

GET 的响应报文


POST 的响应报文


2.5 post 请求体参数格式

  • Content-Type: application/x-www-form-urlencoded;charset=utf-8

    • 用于键值对参数,参数的键值用 = 连接,参数之间用 & 连接
    • 例如: name=%E5%B0%8F%E6%98%8E&age=12
  • Content-Type: application/json;charset=utf-8
    • 用于 json 字符串参数
    • 例如: {"name": "%E5%B0%8F%E6%98%8E", "age": 12}
  • Content-Type: multipart/form-data
    • 用于文件上传请求

2.6 响应状态码

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

2.7 不同类型的请求及其作用

  • GET:从服务器端读取数据(查)

  • POST:向服务器端添加新数据 (增)

  • PUT:更新服务器端已经数据 (改)

  • DELETE:删除服务器端数据 (删)

2.8 API 的分类

  • REST API:restful (Representational State Transfer(资源)表现层状态转化)

    • 发送请求进行 CRUD 哪个操作由请求方式来决定
    • 同一个请求路径可以进行多个操作
    • 请求方式会用到GET/POST/PUT/DELETE
  • 非 REST API:restless
    • 请求方式不决定请求的 CRUD 操作
    • 一个请求路径只对应一个操作
    • 一般只有 GET/POST

2.9 区别:一般 http 请求与 ajax 请求

  • ajax 请求是一种特别的 http 请求

  • 对服务器端来说,没有任何区别,区别在浏览器端

  • 浏览器端发请求:只有 XHR 或 fetch 发出的才是 ajax 请求,其它所有的都是非 ajax 请求

  • 浏览器端接收到响应

    • 一般请求:浏览器一般会直接显示响应体数据,也就是我们常说的刷新/跳转页面
    • ajax 请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数并传入响应相关数据

3 原生 AJAX 的基本使用 XHR

3.0 准备工作

3.0.1 安装 node.js

http://nodejs.cn/

3.0.2 安装 express(服务端框架)

https://www.expressjs.com.cn/

初始化环境

npm init --yes

下载express包

npm install express --save

编写js代码

// 1. 引入express
const express = require('express');// 2. 创建应用对象
const app = express();// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/', (request, response) => {//  设置响应response.send("Hello Express");
});// 4. 监听端口,启动服务
app.listen(8000, () => {console.log("服务已经启动, 8000 端口监听中...");})

运行 js 程序

node express基本使用.js

3.0.3 安装 nodemon 自动重启工具

文件内容有修改自动重新启动服务

https://nodemon.io/

安装

npm install -g nodemon

启动服务

nodemon server.js

3.1 理解

  • 使用 XMLHttpRequest (XHR)对象可以与服务器交互,也就是发送 ajax 请求
  • 前端可以获取到数据,而无需让整个的页面刷新
  • 这使得 Web 页面可以只更新页面的局部,而不影响用户的操作

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

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

3.2 核心对象使用步骤

3.2.1 创建 XMLHttpRequest 对象

// 方法一:直接创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 方法二:兼容IE
var xhr = null;
if(window.XMLHttpRequest){// 标准模式下xhr = new XMLHttpRequest();
}else{// IE独有的ajax对象xhr = new ActiveXObject('Microsoft.XMLHTTP')
}

3.2.2 设置请求信息(请求方法和url)

// 请求方式
xhr.open(method, url);
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

3.2.3 发送请求

xhr.send(body) //get请求不传 body 参数,只有post请求使用

3.2.4 接收响应(事件绑定,处理服务端返回的结果)

//xhr.responseXML 接收 xml格式 的响应数据
//xhr.responseText 接收 文本格式 的响应数据
xhr.onreadystatechange = function (){// readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4if(xhr.readyState == 4 && xhr.status == 200){var text = xhr.responseText;console.log(text);}
}

3.3 GET 请求

点击返回响应信息

创建两个文件,浏览器端使用的 html 文件服务器端使用的 js 文件

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 接收GET类型的请求,且路径为/server
app.get('/server', (request, response)=>{// 设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应response.send('HELLO AJAX GET');
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

启动服务

node server.js

前端页面 GET.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax GET请求</title><style>#result{width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><!-- 点击按钮时发送请求 --><button>点击发送请求</button><div id="result"></div><script>// 获取button元素const btn = document.getElementsByTagName('button')[0];const result = document.getElementById('result');// 绑定事件btn.onclick = function(){// 1.创建对象const xhr = new XMLHttpRequest();// 2.初始化 设置请求方法和url// xhr.open('GET', 'http://127.0.0.1:8000/server');// GET传参方法:参数写在url里xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');// 3.发送xhr.send();// 4.事件绑定 处理服务端返回的结果xhr.onreadystatechange = function(){// 判断服务端是否返回了所有结果if (xhr.readyState === 4) {// 判断响应状态码// 2xx都表示成功,不只有200,判断条件可写成xhr.status >= 200 && xhr.status <= 200if (xhr.status === 200) {// 处理结果 行 头 空行 体// 响应行console.log(xhr.status);// 状态码console.log(xhr.statusText);// 状态字符串console.log(xhr.getAllResponseHeaders);// 所有响应头console.log(xhr.response);// 响应体// 设置result文本result.innerHTML = xhr.response;}}}}</script>
</body>
</html>

3.4 POST 请求

鼠标放到 div 中,发 post 请求,将响应体放在 div 中呈现

服务器端 server.js 添加 post

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 接收POST类型的请求,且路径为/server
app.post('/server', (request, response)=>{// 设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应response.send('HELLO AJAX POST');
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

前端页面 POST.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax POST请求</title><style>#result{width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><!-- 获得焦点时发送请求 --><div id="result"></div><script>// 获取元素对象const result = document.getElementById('result');// 绑定事件result.addEventListener('mouseover', function(){// 1.创建对象const xhr = new XMLHttpRequest();// 2.初始化 设置类型与URLxhr.open('POST', 'http://127.0.0.1:8000/server');// 3.发送// xhr.send();// POST传参方法:参数写在send方法里,书写格式随意// xhr.send('a=100&b=200&c=300');xhr.send('a:100&b:200&c:300');// 4.事件绑定xhr.onreadystatechange = function(){// 判断if (xhr.readyState === 4) {if(xhr.status === 200){// 处理服务端返回的结果result.innerHTML = xhr.response}}}})</script>
</body>
</html>

3.5 设置请求头信息

前端页面 POST.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax POST请求</title><style>#result{width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><!-- 获得焦点时发送请求 --><div id="result"></div><script>// 获取元素对象const result = document.getElementById('result');// 绑定事件result.addEventListener('mouseover', function(){// 1.创建对象const xhr = new XMLHttpRequest();// 2.初始化 设置类型与URLxhr.open('POST', 'http://127.0.0.1:8000/server');// 设置请求头// 预定义的请求头,e.g.设置请求体内容的类型xhr.setRequesHeader('Content-Type','application/x-www-from-urlencoded');// 自定义头信息xhr.setRequesHeader('name', 'ykyk');// 3.发送// xhr.send();// POST传参方法:参数写在send方法里,书写格式随意// xhr.send('a=100&b=200&c=300');xhr.send('a:100&b:200&c:300');// 4.事件绑定xhr.onreadystatechange = function(){// 判断if (xhr.readyState === 4) {if(xhr.status === 200){// 处理服务端返回的结果result.innerHTML = xhr.response}}}})</script>
</body>
</html>

服务器端 server.js 添加 all,设置响应头允许自定义请求头

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 可以接收任意类型的请求,且路径为/server,可用来设置响应头允许自定义请求头
app.all('/server', (request, response) => {//设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');//响应头response.setHeader('Access-Control-Allow-Headers', '*');//设置响应体response.send('HELLO AJAX ALL');
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

3.6 JSON 数据请求

前端页面 JSON.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax JSON数据</title><style>#result{width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><!-- 点击按钮时发送请求 --><div id="result"></div><script>// 获取元素对象const result = document.getElementById('result');// 绑定键盘按下事件window.onkeydown = function(){// 发送请求const xhr = new XMLHttpRequest();// 设置响应体数据类型xhr.responseType = 'json';// 初始化xhr.open('GET', 'http://127.0.0.1:8000/json-server');// 发送xhr.send();// 事件绑定xhr.onreadystatechange = function(){// 判断if (xhr.readyState === 4) {if(xhr.status === 200){// 处理服务端返回的结果// console.log(xhr.response);// result.innerHTML = xhr.response;// 手动对数据进行转化// let data = JSON.parse(xhr.response);// console.log(data);// result.innerHTML = data.name;// 自动转换console.log(xhr.response);result.innerHTML = xhr.response.name;}}}}</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 可以接收任意类型的请求,且路径为/json-server
app.all('/json-server', (request, response) => {//设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');//响应头response.setHeader('Access-Control-Allow-Headers', '*');//设置响应体// response.send('HELLO AJAX JSON');// 响应一个数据const data = {name: 'lemon',age: '18'}// 对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

3.7 IE 缓存问题

前端页面 IE.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax GET请求</title><style>#result{width: 200px;height: 100px;border: solid 1px #90b;}</style>
</head>
<body><!-- 点击按钮时发送请求 --><button>点击发送请求</button><div id="result"></div><script>// 获取button元素const btn = document.getElementsByTagName('button')[0];const result = document.getElementById('result');btn.addEventListener('click', function(){const xhr = new XMLHttpRequest();// 添加参数使得url每次都不同,e.g.时间戳xhr.open('GET', 'http://127.0.0.1:8000/ie?t=' + Date.now());xhr.send();xhr.onreadystatechange = function(){if (xhr.readyState === 4) {if (xhr.status === 200) {result.innerHTML = xhr.response;}}}})</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 针对IE缓存
app.get('/ie', (request, response)=>{// 设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应response.send('HELLO IE');
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

3.8 请求超时与网络异常

前端页面 超时与网络异常.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>请求超时与网络异常</title><style>#result{width:200px;height:100px;border:solid 1px #90b;}</style>
</head>
<body><button>点击发送请求</button><div id="result"></div><script>const btn = document.getElementsByTagName('button')[0];const result = document.querySelector('#result');btn.addEventListener('click', function(){const xhr = new XMLHttpRequest();// 超时设置 2s,正常获取数据// xhr.timeout = 2000;//超时设置 0.5s,获取数据失败xhr.timeout = 500;//超时回调xhr.ontimeout = function(){alert("请求超时, 请稍后重试!!");}//网络异常回调xhr.onerror = function(){alert("你的网络似乎出了一些问题!");}xhr.open("GET",'http://127.0.0.1:8000/delay');xhr.send();xhr.onreadystatechange = function(){if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status< 300){result.innerHTML = xhr.response;}}}})</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 延时响应
app.all('/delay', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');setTimeout(() => {// 设置响应体response.send('延时响应');}, 1000)
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

3.9 取消请求

前端页面 取消请求.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>取消请求</title>
</head>
<body><button>点击发送</button><button>点击取消</button><script>//获取元素对象const btns = document.querySelectorAll('button');let x = null;btns[0].onclick = function(){x = new XMLHttpRequest();x.open("GET",'http://127.0.0.1:8000/delay');x.send();}// abortbtns[1].onclick = function(){x.abort();}</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 延时响应
app.all('/delay', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');setTimeout(() => {// 设置响应体response.send('延时响应');}, 1000)
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

3.10 请求重复发送问题

前端页面 请求重复发送问题.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>重复请求问题</title>
</head>
<body><button>点击发送</button><script>//获取元素对象const btns = document.querySelectorAll('button');let x = null;//标识变量let isSending = false; // 是否正在发送AJAX请求btns[0].onclick = function(){//判断标识变量if(isSending) x.abort();// 如果正在发送, 则取消该请求, 创建一个新的请求x = new XMLHttpRequest();//修改 标识变量的值isSending = true;x.open("GET",'http://127.0.0.1:8000/delay');x.send();x.onreadystatechange = function(){if(x.readyState === 4){//修改标识变量isSending = false;}}}// abortbtns[1].onclick = function(){x.abort();}</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 延时响应
app.all('/delay', (request, response) => {//设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');setTimeout(() => {// 设置响应体response.send('延时响应');}, 1000)
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

4 jQuery 发送请求

4.1 get 请求

$.get(url, [data], [callback], [type])
  • url:请求的 URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml html script json text _default

4.2 post 请求

$.post(url, [data], [callback], [type])

url:请求的 URL 地址

data:请求携带的参数

callback:载入成功时回调函数

type:设置返回内容格式,xml html script json text _default

前端页面 client.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery 发送 AJAX 请求</title><link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body><div class="container"><h2 class="page-header">jQuery发送AJAX请求 </h2><button class="btn btn-primary">GET</button><button class="btn btn-danger">POST</button><button class="btn btn-info">通用型方法ajax</button></div><script>$('button').eq(0).click(function(){$.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){console.log(data);},'json');});$('button').eq(1).click(function(){$.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){console.log(data);});});$('button').eq(2).click(function(){$.ajax({//urlurl: 'http://127.0.0.1:8000/jquery-server',//参数data: {a:100, b:200},//请求类型type: 'GET',//响应体结果dataType: 'json',//成功的回调success: function(data){console.log(data);},//超时时间timeout: 2000,//失败的回调error: function(){console.log('出错啦!!');},//头信息headers: {c:300,d:400}});});</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 延时响应
app.all('/delay', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');setTimeout(() => {// 设置响应体response.send('延时响应');}, 1000)
});// jQuery 服务
app.all('/jquery-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');// response.send('Hello jQuery AJAX');const data = {name:'lemon'};response.send(JSON.stringify(data));
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

5 Axios 发送请求

前端页面 axios.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>axios 发送 AJAX请求</title><script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head><body><button>GET</button><button>POST</button><button>AJAX</button><script>// https://github.com/axios/axiosconst btns = document.querySelectorAll('button');//配置 baseURLaxios.defaults.baseURL = 'http://127.0.0.1:8000';//GET 请求btns[0].onclick = function () {axios.get('/axios-server', {// 第二个参数--url参数params: {id: 100,vip: 7},// 第三个参数--请求头信息headers: {name: 'atguigu',age: 20}}).then(value => {console.log(value);});}//POST 请求btns[1].onclick = function () {axios.post('/axios-server',{// 第二个参数--请求体username: 'admin',password: 'admin'},{// 第三个参数--url参数params: {id: 200,vip: 9},// 第四个参数--请求头信息headers: {height: 180,weight: 180,}});}//AJAX 请求btns[2].onclick = function(){axios({//请求方法method : 'POST',//urlurl: '/axios-server',//url参数params: {vip:10,level:30},//头信息headers: {a:100,b:200},//请求体信息data: {username: 'admin',password: 'admin'}}).then(response => {//响应状态码console.log(response.status);//响应状态字符串console.log(response.statusText);//响应头信息console.log(response.headers);//响应体console.log(response.data);})}</script>
</body></html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// axios 服务
app.all('/axios-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');// response.send('Hello jQuery AJAX');const data = {name:'lemon'};response.send(JSON.stringify(data));
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

6 fetch 发送请求

https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch

前端页面 fetch.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>fetch 发送 AJAX请求</title>
</head>
<body><button>AJAX请求</button><script>const btn = document.querySelector('button');btn.onclick = function(){fetch('http://127.0.0.1:8000/fetch-server?vip=10', {//请求方法method: 'POST',//请求头headers: {name:'haha'},//请求体body: 'username=admin&password=admin'}).then(response => {// return response.text();return response.json();}).then(response=>{console.log(response);});}</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// fetch 服务
app.all('/fetch-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');// response.send('Hello jQuery AJAX');const data = {name:'lemon'};response.send(JSON.stringify(data));
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

7 跨域

7.1 同源策略

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

前端页面 index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>首页</title>
</head>
<body><h1>lemon</h1><button>点击获取用户数据</button><script>const btn = document.querySelector('button');btn.onclick = function(){const x = new XMLHttpRequest();// 这里因为是满足同源策略的, 所以 url 可以简写x.open("GET",'/data');// 发送x.send();x.onreadystatechange = function(){if(x.readyState === 4){if(x.status >= 200 && x.status < 300){console.log(x.response);}}}}</script>
</body>
</html>

服务器端 server.js

const express = require('express');const app = express();app.get('/home', (request, response)=>{// 响应一个页面response.sendFile(__dirname + '/index.html');
});app.get('/data', (request, response)=>{response.send('用户数据');
});app.listen(9000, ()=>{console.log("服务已经启动...");
});

7.2 JSONP

  • JSONP 是什么

    • JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get 请求
  • JSONP 怎么工作的
    • 在网页有一些标签天生具有跨域能力,比如:img link iframe script
    • JSONP 就是利用 script 标签的跨域能力来发送请求的

7.2.1 原理

前端页面 index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>原理演示</title><style>#result {width: 300px;height: 100px;border: solid 1px #78a;}</style>
</head><body><div id="result"></div><script>// 处理数据function handle(data) {// 获取 result 元素const result = document.getElementById('result');result.innerHTML = data.name;}</script><!-- <script src="http://127.0.0.1:5500/%E8%AF%BE%E5%A0%82/%E4%BB%A3%E7%A0%81/7-%E8%B7%A8%E5%9F%9F/2-JSONP/js/app.js"></script> --><script src="http://127.0.0.1:8000/jsonp-server"></script>
</body></html>

服务器端 app.js

const data = {name: 'lemon'
};
handle(data);

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// jsonp服务
app.all('/jsonp-server',(request, response) => {// response.send('console.log("hello jsonp")');const data = {name: '尚硅谷atguigu'};// 将数据转化为字符串let str = JSON.stringify(data);// 返回结果response.end(`handle(${str})`);
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

7.2.2 JSONP 实践

前端页面 index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>案例</title>
</head>
<body>用户名: <input type="text" id="username"><p></p><script>// 获取 input 元素const input = document.querySelector('input');const p = document.querySelector('p');// 声明 handle 函数function handle(data){input.style.border = "solid 1px #f00";// 修改 p 标签的提示文本p.innerHTML = data.msg;}// 绑定事件input.onblur = function(){// 获取用户的输入值let username = this.value;//向服务器端发送请求 检测用户名是否存在//1. 创建 script 标签const script = document.createElement('script');//2. 设置标签的 src 属性script.src = 'http://127.0.0.1:8000/check-username';//3. 将 script 插入到文档中document.body.appendChild(script);}</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 用户名检测是否存在
app.all('/check-username',(request, response) => {// response.send('console.log("hello jsonp")');const data = {exist: 1,msg: '用户名已经存在'};// 将数据转化为字符串let str = JSON.stringify(data);// 返回结果response.end(`handle(${str})`);
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

7.2.3 jQuery 中的 JSONP

前端页面 index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jQuery-jsonp</title><style>#result{width:300px;height:100px;border:solid 1px #089;}</style><script crossorigin="anonymous" src='https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js'></script>
</head>
<body><button>点击发送 jsonp 请求</button><div id="result"></div><script>$('button').eq(0).click(function(){$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){$('#result').html(`名称:${data.name}<br>校区:${data.city}`)});});</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// jQuery中的JSONP
app.all('/jquery-jsonp-server',(request, response) => {// response.send('console.log("hello jsonp")');const data = {name:'lemon',city: ['北京','上海','深圳']};// 将数据转化为字符串let str = JSON.stringify(data);// 接收 callback 参数let cb = request.query.callback;// 返回结果response.end(`${cb}(${str})`);
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

7.3 CORS

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

  • CORS 是什么?

    • CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get 和post 请求。跨域资源共享标准新增了一组HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
  • CORS 怎么工作的?
    • CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行

前端页面 cors.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>CORS</title><style>#result{width:200px;height:100px;border:solid 1px #90b;}</style>
</head>
<body><button>发送请求</button><div id="result"></div><script>const btn = document.querySelector('button');btn.onclick = function(){//1. 创建对象const x = new XMLHttpRequest();//2. 初始化设置x.open("GET", "http://127.0.0.1:8000/cors-server");//3. 发送x.send();//4. 绑定事件x.onreadystatechange = function(){if(x.readyState === 4){if(x.status >= 200 && x.status < 300){//输出响应体console.log(x.response);}}}}</script>
</body>
</html>

服务器端 server.js

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// cors跨域
app.all('/cors-server', (request, response)=>{// 设置响应头response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Headers", '*');response.setHeader("Access-Control-Allow-Method", '*');// response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");response.send('hello CORS');
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

8 完整的 server.js 代码

//1. 引入express
const express = require('express');//2. 创建应用对象
const app = express();//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 发送请求时,如果发送路径(请求行的第二个内容)是/server,就会执行函数体里的代码
// 接收GET类型的请求,且路径为/server
app.get('/server', (request, response)=>{// 设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应response.send('HELLO AJAX GET');
});// 接收POST类型的请求,且路径为/server
// app.post('/server', (request, response)=>{
//     // 设置响应头,设置允许跨域
//     response.setHeader('Access-Control-Allow-Origin', '*');
//     // 设置响应
//     response.send('HELLO AJAX POST');
// });// 可以接收任意类型的请求,且路径为/server,可用来设置响应头允许自定义请求头
app.all('/server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 响应头response.setHeader('Access-Control-Allow-Headers', '*');// 设置响应体response.send('HELLO AJAX ALL');
});// 可以接收任意类型的请求,且路径为/json-server
app.all('/json-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 响应头response.setHeader('Access-Control-Allow-Headers', '*');// 设置响应体// response.send('HELLO AJAX JSON');// 响应一个数据const data = {name: 'lemon',age: '18'}// 对对象进行字符串转换let str = JSON.stringify(data);// 设置响应体response.send(str);
});// 针对IE缓存
app.get('/ie', (request, response)=>{// 设置响应头,设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应response.send('HELLO IE');
});// 延时响应
app.all('/delay', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');setTimeout(() => {// 设置响应体response.send('延时响应');}, 1000)
});// jQuery 服务
app.all('/jquery-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');// response.send('Hello jQuery AJAX');const data = {name:'lemon'};response.send(JSON.stringify(data));
});// axios 服务
app.all('/axios-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');// response.send('Hello jQuery AJAX');const data = {name:'lemon'};response.send(JSON.stringify(data));
});// fetch 服务
app.all('/fetch-server', (request, response) => {// 设置响应头  设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');response.setHeader('Access-Control-Allow-Headers', '*');// response.send('Hello jQuery AJAX');const data = {name:'lemon'};response.send(JSON.stringify(data));
});// jsonp服务
app.all('/jsonp-server',(request, response) => {// response.send('console.log("hello jsonp")');const data = {name: '尚硅谷atguigu'};// 将数据转化为字符串let str = JSON.stringify(data);// 返回结果response.end(`handle(${str})`);
});// 用户名检测是否存在
app.all('/check-username',(request, response) => {// response.send('console.log("hello jsonp")');const data = {exist: 1,msg: '用户名已经存在'};// 将数据转化为字符串let str = JSON.stringify(data);// 返回结果response.end(`handle(${str})`);
});// jQuery中的JSONP
app.all('/jquery-jsonp-server',(request, response) => {// response.send('console.log("hello jsonp")');const data = {name:'lemon',city: ['北京','上海','深圳']};// 将数据转化为字符串let str = JSON.stringify(data);// 接收 callback 参数let cb = request.query.callback;// 返回结果response.end(`${cb}(${str})`);
});// cors跨域
app.all('/cors-server', (request, response)=>{// 设置响应头response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Headers", '*');response.setHeader("Access-Control-Allow-Method", '*');// response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");response.send('hello CORS');
});//4. 监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动, 8000 端口监听中....");
});

【AJAX 笔记】AJAX 基本、HTTP 基本、原生 AJAX 的使用,jQuery / Axios / fetch 发送请求、跨域(JSONP/CORS)相关推荐

  1. 解决ajax请求跨域,解决ajax请求跨域

    跨域大部分需要通过后台解决,引起跨域的原因: 3个问题同时满足 才可能产生跨域问题,即跨域(协议,主机名,端口号中有一个不同就产生跨域) 下面是解决方法 方法一 // ajax请求跨域 /* *解决a ...

  2. [JS]笔记18_AJAX2_iframe元素AJAX跨域JSONP跨域

    1.iframe元素 iframe元素会创建包含另外一个文档的内联框架 常用属性: frameborder属性规定是否显示框架周围的边框 值:0/1 src属性规定要显示的文档的URL 可是:html ...

  3. 【JS】AJAX跨域-JSONP解决方案(一)

    [JS]AJAX跨域-JSONP解决方案(一) 参考文章: (1)[JS]AJAX跨域-JSONP解决方案(一) (2)https://www.cnblogs.com/h--d/p/11470534. ...

  4. 关于ajax post请求跨域问题的解决心得

    关于ajax post请求跨域问题的解决心得 参考文章: (1)关于ajax post请求跨域问题的解决心得 (2)https://www.cnblogs.com/guaishushulz/p/670 ...

  5. ajax跨域jsonp并且post请求No 'Access-Control-Allow-Origin'以及执行error时readyState=4同时status=200的解决方法

    ajax跨域jsonp并且post请求No 'Access-Control-Allow-Origin'以及执行error时readyState=4同时status=200的解决方法 [网上很多网友的回 ...

  6. WebApp开发:ajax请求跨域问题的解决

    WebApp开发:ajax请求跨域问题的解决 参考文章: (1)WebApp开发:ajax请求跨域问题的解决 (2)https://www.cnblogs.com/code-style/p/42094 ...

  7. AJAX | 跨域与JSONP + 同源策略和跨域 + JSONP + 防抖和节流 + 案例 – 淘宝搜索

    目录 同源策略和跨域 同源策略 跨域 JSONP JSONP的实现原理 自己实现一个简单的JSONP JSONP的缺点 jQuery中的JSONP 自定义参数及回调函数名称 jQuery中JSONP的 ...

  8. ajax jq 图片上传请求头_全面分析前端的网络请求方式:Ajax ,jQuery ,axios,fetch

    链接:https://juejin.im/post/5c9ac607f265da6103588b31 一.前端进行网络请求的关注点 大多数情况下,在前端发起一个网络请求我们只需关注下面几点: 传入基本 ...

  9. AJAX跨域资源共享 CORS 详解

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

最新文章

  1. jsp自定自定义标签
  2. hive值乘以0.01保留一位小数_Hive窗口函数01-SUM、MIN、MAX、AVG
  3. 如何正确使用网站TAG标签,让SEO优化效果倍增?
  4. c语言怎样判断键盘 输入法,如何快速的认识键盘和正确的使用键盘
  5. 指针嵌套指针 拷贝_C++智能指针小结
  6. 【渝粤题库】广东开放大学 公共部门人力资源管理 形成性考核
  7. 工作395-路由选择
  8. 使用java实现面向对象编程第二章_java面向对象编程——第二章 java基础语法
  9. Mysql 中创建数据库并插入数据
  10. 三七互娱U3D面经2021.3.31
  11. Django_modelform组件
  12. 《药物设计学》单词表
  13. 人体姿态2018(五)Can 3D Pose be Learned from 2D Projections Alone?
  14. server 2008 r2 怎么打开任务管理?
  15. jquerykindeditor文本编辑器插件
  16. MyHome3D在线装修设计软件测评
  17. 统计微信好友性别,并可视化
  18. 【华人学者风采】韩竹 休斯顿大学
  19. html5 3d场景设计,H5打造3d场景不完全攻略(二): Amazing CSS3D
  20. Draw Call是什么?

热门文章

  1. HAL库STM32F103C8T6超声波测距
  2. mui mui-icon-extra的使用
  3. html 点击事件阻止冒泡,js阻止事件冒泡的两种方法
  4. pub格式文件如何打开
  5. QC4+充电协议_五一开黑告别电量焦虑 这些充电协议不知道还真不行
  6. linux系统更改ip无法保存,解决win10修改IP无法保存并提示“出现了一个意外情况”的方法...
  7. 【统计分析】(task2) 假设检验2:多元数值向量检验
  8. 自己总结的MySQL基础入门知识,附思维导图
  9. IDEA代码重构小技巧(VIP典藏版)
  10. vs cdoe 配置c和c++环境