AJAX 简介

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。

通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。

AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

XML 简介

XML 可扩展标记语言。

XML 被设计用来传输和存储数据。

XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,

全都是自定义标签,用来表示一些数据。

现在已经被JSON取代了

AJAX 的特点

AJAX 的优点

  1. 可以无需刷新页面而与服务器端进行通信。

  2. 允许你根据用户事件来更新部分页面内容。

AJAX的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. SEO 不友好 (爬虫爬不到)

HTTP

HTTP(hypertext transport protocol)协议『超文本传输协议』,协议详细规定了浏览器和万维网服务器之间互相通信的规则。
约定, 规则

请求报文

重点是格式与参数

1
2
3
4
5
6
7
行      POST  /s?ie=utf-8  HTTP/1.1 
头 Host: atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83
空行
体 username=admin&password=admin

响应报文

1
2
3
4
5
6
7
8
9
10
11
12
行      HTTP/1.1  200  OK
头 Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
体 <html>
<head>
</head>
<body>
<h1>啦啦啦</h1>
</body>
</html>

Node.js express 框架

安装nodejs

这里我推荐使用 nvm 来管理 node 的版本,因为在我做项目过程中,可能需要维护别人的老项目,所以node版本经常不匹配,使用 nvm 进行node 版本的管理,可用方便的切换不同版本的 node 。

windows的话,可以在github上下载nvm 打开我们可以看到两个版本

  • nvm-noinstall.zip:绿色免安装版,但使用时需进行配置

  • nvm-setup.zip:安装版,推荐使用

nvm的具体安装和使用简书Do_Du有详细的步骤,可以进行参考

使用express框架

Express 是一个简洁而灵活的 node.js Web应用框架, 提供一系列强大特性帮助你创建各种Web应用

在文件夹路径下的cmd中,初始化项目 npm init --yes

安装 express : npm i express

使用express

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// express基本使用.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 端口监听中....");
});

写好文件后,在文件所在路径的cmd中 使用 node 来启动服务器:node express基本使用.js 可以看到服务已经启动,cmd中打印出了 “服务已经启动, 8000 端口监听中....” 字样

测试代码

在下文前端的代码中,发送请求要用的文件为 server.js 是使用 express 框架搭建的,全部代码在如下,跑起来 node 服务后就可以进行 ajax 请求的发送

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//1. 引入express
const express = require('express');

//2. 创建应用对象
const app = express();

//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//设置响应体
response.send('HELLO AJAX - 2');
});

//可以接收任意类型的请求
app.all('/server', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//响应头
response.setHeader('Access-Control-Allow-Headers', '*');
//设置响应体
response.send('HELLO AJAX POST');
});

//JSON 响应
app.all('/json-server', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//响应头
response.setHeader('Access-Control-Allow-Headers', '*');
//响应一个数据
const data = {
name: 'atguigu'
};
//对对象进行字符串转换
let str = JSON.stringify(data);
//设置响应体
response.send(str);
});

//针对 IE 缓存
app.get('/ie', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//设置响应体
response.send('HELLO IE - 5');
});

//延时响应
app.all('/delay', (request, response) => {
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
setTimeout(() => {
//设置响应体
response.send('延时响应');
}, 3000)
});

//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:'尚硅谷'};
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:'尚硅谷'};
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:'尚硅谷'};
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})`);
});

//
app.all('/jquery-jsonp-server',(request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
name:'尚硅谷',
city: ['北京','上海','深圳']
};
//将数据转化为字符串
let str = JSON.stringify(data);
//接收 callback 参数
let cb = request.query.callback;

//返回结果
response.end(`${cb}(${str})`);
});

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

GET请求

启动写好的server.js : node server.js

点击按钮 ,获取响应显示在div中

创建一个 XMLHttpRequest() 对象

使用 open方法,初始化请求方法和url (对于需要传参数的get请求,直接在url后面拼接参数)

使用send方法来发送请求

绑定onreadystatechange事件,处理返回的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//获取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?a=100&b=200&c=300');
//3. 发送
xhr.send();
//4. 事件绑定 处理服务端返回的结果
//onreadystatechange事件:
// on when 当....时候
// readystate 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
// change 改变
xhr.onreadystatechange = function(){
//判断 (服务端返回了所有的结果 这个时候状态是 4 )
if(xhr.readyState === 4){
//判断响应状态码 200 404 403 401 500
// 2xx 成功
if(xhr.status >= 200 && xhr.status < 300){
//处理结果 行 头 空行 体
//响应
console.log(xhr.status);//状态码
console.log(xhr.statusText);//状态字符串
console.log(xhr.getAllResponseHeaders());//所有响应头
console.log(xhr.response);//响应体
//设置 result 的文本
result.innerHTML = xhr.response;
}else{

}
}
}
}

POST请求

过程和get请求差不多,

设置参数的时候,在send方法中设置,

不论get还是post 都可以设置请求头,不过post常用,通过 setRequestHeader来设置请求头

server.js 前端人员不用管其实。但是如果设置了自定义字段的请求头。server.js需要添加response.setHeader('Access-Control-Allow-Headers', '*');

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//获取元素对象
const result = document.getElementById("result");
//绑定事件
result.addEventListener("mouseover", function(){
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化 设置类型与 URL
xhr.open('POST', 'http://127.0.0.1:8000/server');
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','atguigu');
//3. 发送
xhr.send('a=100&b=200&c=300');
// xhr.send('a:100&b:200&c:300');
// xhr.send('1233211234567');

//4. 事件绑定
xhr.onreadystatechange = function(){
//判断
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
//处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
}
});

处理服务端返回的json数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 && xhr.status < 300){
//
// console.log(xhr.response);
// result.innerHTML = xhr.response;
// 1. 手动对数据转化
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = data.name;
// 2. 自动转换
console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}

对于处理服务端返回的json格式字符串,我们有两种方法来处理

  1. 手动处理

    1
    2
    3
    4
    // 使用JSON parse 方法 把json格式字符串转换为json 实现字符串转json ,然后就可以操作json数据了
    let data = JSON.parse(xhr.response);
    console.log(data);
    result.innerHTML = data.name;
  2. 自动处理

    1
    2
    3
    // 利用XMLHttpRequest 对象自带的方法,设置接收的响应为json格式,那么response会自动转换为json格式,直接操作json格式的response就好了
    xhr.responseType = 'json';
    console.log(xhr.response);

IE 缓存问题

ie 浏览器会把 ajax 请求缓存起来,下次再请求的话,就会请求本地的数据,对于时效性强的页面不好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const btn = document.getElementsByTagName('button')[0];
const result = document.querySelector('#result');
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest();
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 && xhr.status< 300){
result.innerHTML = xhr.response;
}
}
}
})

对于缓存问题,只有请求的东西完全一样才会走缓存,所以我们给请求加上一个时间戳参数Date.now(),这样就每次都是去服务器请求数据。

超时和网络异常问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const btn = document.getElementsByTagName('button')[0];
const result = document.querySelector('#result');
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest();
//超时设置 2s 设置
xhr.timeout = 2000;
//超时回调
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;
}
}
}
})

在这个案例中,server.js 中设置了延迟响应来模拟响应超时。

通过 XMLHttpRequest 的timeout 来设置超时的时间,即超过这个时间,就判定它是超时的。

通过 ontimeout 来设置超时的回调函数,即超时后怎么处理
通过 onerror 来设置断网的回调函数。

取消请求

1
2
3
4
5
6
7
8
9
10
11
12
//获取元素对象
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();
}
// abort
btns[1].onclick = function(){
x.abort();
}

使用 XMLHttpRequest 的abort方法来请求数据

重复请求问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//获取元素对象
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;
}
}
}

通过一个标识变量,如果请求已经发送了,正在加载,就停止后面重复发送的请求。

JQuery 中的ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$('button').eq(0).click(function(){
// 发送get 请求, 第四个参数是设置响应的数据类型
$.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请求,只用把get换成post就好了
$.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
});
});

// 通用的请求方法 ajax
$('button').eq(2).click(function(){
$.ajax({
//url
url: '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
}
});
});

axios 发送 ajax 请求

axios 是目前发送ajax 请求比较热门的工具包

可以安装也可以直接通过链接引入<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// https://github.com/axios/axios
const btns = document.querySelectorAll('button');

//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';

btns[0].onclick = function () {
//GET 请求
axios.get('/axios-server', {
//url中拼接的参数
params: {
id: 100,
vip: 7
},
//请求头信息
headers: {
name: 'atguigu',
age: 20
}
}).then(value => {
console.log(value);
});
}

btns[1].onclick = function () {
// 发送post请求 请求体放在第二个参数的位置,
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
}, {
//url 中拼接的参数
params: {
id: 200,
vip: 9
},
//请求头参数
headers: {
height: 180,
weight: 180,
}
});
}

btns[2].onclick = function(){
axios({
//请求方法
method : 'POST',
//url
url: '/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);
})
}

Fetch函数发送请求

fetch函数属于全局对象,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//文档地址
//https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
//请求方法
method: 'POST',
//请求头
headers: {
name:'atguigu'
},
//请求体
body: 'username=admin&password=admin'
}).then(response => {
// return response.text();
// 就看响应的是什么 可以用json直接解析出json字符串
return response.json();
}).then(response=>{
console.log(response);
});
}

跨域

同源策略

同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略

同源: 协议、域名、端口号 必须完全相同。

违背同源策略就是跨域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//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("服务已经启动...");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!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>lalal</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>

jsonp 解决跨域

JSONP 是什么

  • JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持 get 请求。

JSONP 怎么工作的?

  • 在网页有一些标签天生具有跨域能力,比如:img link iframe script。
  • JSONP 就是利用 script 标签的跨域能力来发送请求的

JSONP 的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!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>

通过js 创建一个script 标签,在标签的src中写入需要跨域的路径,然后服务器返回一个js格式的数据实现跨域效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//server.js
//用户名检测是否存在
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!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>

发送请求的时候,需要加一个callback参数,返回的时候,获取到该参数,改参数就是getjson里面的回调函数的意思,返回对回调函数的调用,就可以实现对数据的渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//server.js

app.all('/jquery-jsonp-server',(request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
name:'尚硅谷',
city: ['北京','上海','深圳']
};
//将数据转化为字符串
let str = JSON.stringify(data);
//接收 callback 参数
let cb = request.query.callback;

//返回结果
response.end(`${cb}(${str})`);
});

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 的使用

前端就按照ajax 的方法写就好了,cors 是在后端的处理。在后端设置一个响应头,允许跨域

1
2
3
4
5
6
7
8
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');
});