目录
1.Ajax 概述
1.1 AJAX 简介
AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势: 无刷新获取数据。
大白话:有时候不想页面抖动和跳转,不刷新页面就可以刷新新的数据,是前后端最常用的交互方式
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
1.2 XML 简介
XML 可扩展标记语言(Extensible Markup Language)
XML 被设计用来传输和存储数据。
XML 和 HTML 类似,不同的是 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 不友好(搜索引擎,爬虫爬不到 ajax 更新的东西)
2. AJAX 的使用
2.1 使用步骤
核心对象
XMLHttpRequest
AJAX 所有操作都是通过该对象进行的
使用步骤
- 初始化环境, 下载 express 包
# npm init --yes 初始化
# npm i express 安装express
- 编写 js 代码 server.js
// 1. 引入express
const express = require('express');
// 2. 创建应用对象
const app = express();
// 2.1暴露静态资源
app.use(express.static(__dirname+'/src'))
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/test_get', (request, response) => {
// 设置响应
console.log("有人请求test_get了");
response.send("Hello_test_get");
});
// 4. 监听端口,启动服务
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/1_ajax小试牛刀.html");
})
- 运行 server.js
node server.js
- 安装 nodemon, 可以自动重启服务器
# npm install -g nodemon
启动服务
# ndoemon server.js
1、ajax 小试牛刀. html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta >
<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.创建xhr的实例对象
const xhr = new XMLHttpRequest();
//2.指定发送请求方法method和url
xhr.open('GET','http://127.0.0.1:8080/test_get');
//3.发送请求
xhr.send();
//4.事件绑定 处理服务端返回的结果
// 当 准备 状态 发生变化
xhr.onreadystatechange = function(){
/* if(xhr.readyState ===1){
xhr.setRequestHeader('demo',123)//配置请求头
}*/
/* if(xhr.readyState ===2){
xhr.setRequestHeader('demo',123)//配置请求头--报错(send已经调用了,已经无法修改请求头)
}*/
/* if(xhr.readyState ===3){
console.log('3时接收到的数据',xhr.response);//小的数据已经回来了
console.log('3时接收到的响应头',xhr.getAllResponseHeaders());//所有响应头
}*/
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
// 处理 行 头 空行 体
//响应行
// console.log(xhr.status);//http的状态码
// console.log(xhr.statusText);//状态字符串
// console.log(xhr.getAllResponseHeaders());//所有响应头
console.log(xhr.response);//返回的数据
//设置result的文本
result.innerHTML = xhr.response;
}
}
}
</script>
</body>
</html>
readystate 是 xhr 对象中的属性,有 5 种状态 0,1,2,3,4,变化 4 次 (了解即可)
0: 实例出来的那一刻就是0,初始状态
1: 服务器连接已建立,(open已经调用,但是send还没有调用,此时可以修改请求头内容)
2: 请求已接收(send已经调用了,已经无法修改请求头)
3: 请求处理中 (已经回来一部分数据,小的数据已经在此阶段接受完毕,较大的数据等待进一步的接收)
4: 请求已完成,且响应已就绪(数据全部接受完毕)
2.2 完整 get 请求 带参数(会手写)
server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname+'/src'))
// 响应GET请求 #
app.get('/test_get', (request, response) => {
console.log("有人请求test_get了,携带的query参数是:",request.query);
response.send("Hello_test_get");
});
// 响应GET请求 #2
app.get('/test_get2/:name/:age', (request, response) => {
console.log("有人请求test_get2了,携带的params参数是:",request.qparams);
response.send("Hello_test_get2");
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/3_ajax——get请求.html");
})
3、ajax——get 请求. html (面试需完整手写)
btn.onclick = function(){
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)){
console.log(xhr.response);//返回的数据
}
}
/*
需要掌握(query和params的形式)
1.形如:key=value&key=value 就是query参数的 urlencoded 编码形式
2.形如:/xx/xxx/ 老刘/18 就是params参数
*/
//2.指定发送请求方法method和url
xhr.open('GET','http://127.0.0.1:8080/test_get?name=老刘&age=18'); //携带query参数,使用urlencoder编码
//xhr.open('GET','http://127.0.0.1:8080/test_get2/老刘/18'); //携带params参数
//3.发送请求
xhr.send();
}
2.3 完整 post 请求 带参数(会手写)
server.js
const express = require('express');
const app = express();
//使用中间件解析urlencoded编码形式的请求体参数
//app.use(express.urlencoded({extended:true}))
//使用中间件解析json编码形式的请求体参数
app.use(express.json())
app.use(express.static(__dirname+'/src'))
// 响应POST请求
/* post方式可以接收query和params参数(但一般不这么用)
app.post('/test_post/:name/:age',(request,response)=>{
console.log("有人请求test_post了",request.params);
response.send("Hello_test_post");
});
*/
//post方式的接收请求体参数
app.post('/test_post/:name/:age',(request,response)=>{
console.log("有人请求test_post了",request.body);
response.send("Hello_test_post");
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/4_ajax——post请求.html");
})
4、ajax——post 请求 (面试需完整手写)
btn.onclick = function(){
// 1
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
console.log(xhr.response);//返回的数据
}
}
/* post 可以带query和params参数,但是很少用
// 1 xhr.open('POST','http://127.0.0.1:8080/test_post?name=老刘&age=18');
// 2 xhr.open('POST','http://127.0.0.1:8080/test_post/老刘/18'); //携带params参数
xhr.send();
*/
// 2 指定发送请求的:method、url、参数
xhr.open('POST','http://127.0.0.1:8080/test_post')
// 追加请求响应头用于识别携带的请求体参数的编码形式-urlencoded
// xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 追加请求响应头用于识别携带的请求体参数的编码形式-json
xhr.setRequestHeader('Content-Type','application/json');
// 3 发送请求
// 携带urlencoded编码形式的请求体参数
//xhr.send(name=老刘&age=18);
// 携带json编码形式的请求体参数
const person = {name:'老刘',age:18}
xhr.send(JSON.stringify(person));
}
2.4 解析 json 数据
server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname+'/src'))
//post方式的接收请求体参数
app.get('/get_person',(request,response)=>{
console.log("有人请求get_person了");
const person ={name:'老刘',age:18,sex='女'}
response.send(JSON.stringify(person))
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/5_ajax_解析json数据.html");
})
5、ajax_解析 json 数据. html
btn.onclick = function(){
// 1
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
console.log(xhr.response);//返回的数据
}
/* 手动解析json
const {name,age,sex}= JSON.parse(xhr.response);//返回的数据 解构赋值
*/
const {name,age,sex} = xhr.response;
content.innerHTML=(`
<ul>
<li>姓名:${name}</li>
<li>年龄:${age}</li>
<li>性别:${sex}</li>
</ul>`)
}
// 2 指定发送请求的:method、url、参数
xhr.open('GET','http://127.0.0.1:8080/get_person')
// responseType用于指定返回数据的格式
xhr.responseType='json'
// 3 发送请求
xhr.send();
}
2.5 解构赋值连续写法(补充)
let obj= {a:1,b:{c:2}}
//标准解构赋值
const {c} = obj.b
//连续解构赋值
const {b:{c}}=obj
console.log(c);
//连续解构赋值+重命名
const {b:{c:value}}=obj
console.log(alue);
2.6 IE 缓存问题 (时间戳)
状态码 304 是服务器请求过了
server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname+'/src'))
// 响应GET请求
app.get('/get_person',(request,response)=>{
console.log("有人请求get_person了");
const person ={name:'海峰',age:18,sex='女'}
response.send(JSON.stringify(person))
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/6_ajax_处理IE浏览器GET请求缓存问题.html");
})
6、ajax_处理 IE 浏览器 GET 请求缓存问题. html
IE缓存问题:每次请求的链接相同,IE发现链接与之前的相同,不与服务器连接,返回的还是之前的数据。
btn.onclick = function(){
// 1
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
console.log(xhr.response);//返回的数据
}
}
// 2 指定发送请求的:method、url、参数
// 加个时间戳,使每次请求的链接不同
xhr.open('GET','http://127.0.0.1:8080/get_person?time='+Date.now())
// responseType用于指定返回数据的格式
xhr.responseType='json'
// 3 发送请求
xhr.send();
}
2.7 ajax 请求的异常与超时处理
xhr.onerror ( ) 处理请求异常
xhr.ontimeout ( ) 处理请求超时
server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname+'/src'))
// 响应GET请求
app.get('/get_person',(request,response)=>{
console.log("有人请求get_person了");
const person ={name:'海峰',age:18,sex='女'}
response.send(JSON.stringify(person))
});
// 延迟---响应GET请求
app.get('/get_person_delay',(request,response)=>{
console.log("有人请求get_person了");
const person ={name:'tom',age:18,sex='女'}
setTimeout(()=>{
//设置响应体
response.send(JSON.stringify(person));
},3000)
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/7_ajax_请求的异常与超时处理.html");
})
7、ajax_请求的异常与超时处理. html
btn.onclick = function(){
// 1
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
console.log(xhr.response);//返回的数据
}
}
// 2 指定发送请求的:method、url、参数
// xhr.open('GET','http://127.0.0.1:8080/get_person')
xhr.open('GET','http://127.0.0.1:8080/get_person_delay') //带延迟的
// responseType用于指定返回数据的格式
xhr.responseType='json'
// 出错的回调
xhr.onerror = function(){
alert('你的网络似乎出了一点问题');
}
// 超时时间
xhr.timeout = 2000;
// 超时的回调(如果超时了调用)
xhr.ontimeout = function(){
alert('网速不给力,超时了');
}
// 3 发送请求
xhr.send();
}
2.8 ajax 取消请求 xhr.abort( )
8、ajax_取消请求. html
取消请求,有的是服务器接收了请求,取消之后没有返回;有的是服务器还没发过去就取消了。
let xhr; //定义在外面
const btn1 = document.getElementsByTagName('button')[0];
//取消的按钮
const btn2 = document.getElementsByTagName('button')[1];
btn1.onclick = function(){
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
console.log(xhr.response);//返回的数据
}
}
// 2 指定发送请求的:method、url、参数
xhr.open('GET','http://127.0.0.1:8080/get_person_delay') //带延迟的
// responseType用于指定返回数据的格式
xhr.responseType='json'
// 出错的回调
xhr.onerror = function(){
alert('你的网络似乎出了一点问题');
}
// 超时时间
xhr.timeout = 2000;
// 超时的回调
xhr.ontimeout = function(){
alert('网速不给力,超时了');
}
// 3 发送请求
xhr.send();
}
btn2.onclick = function(){
// 取消请求,如果数据已经回来了就取消不了了,如果来得及就会取消
xhr.abort();
}
2.9 避免多次重复请求
9、ajax_避免多次重复请求. html
let xhr; //定义在外面
let isLoading;// 是否正在发送AJAX请求
const btn1 = document.getElementsByTagName('button')[0];
btn1.onclick = function(){
// 设置标志位:如果已经发送请求,之前的就被干掉
if(isLoading) xhr.abort();
// 1 实例xhr
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300){
// 数据已经返回,将标志设为false
isLoading = false;
console.log(xhr.response);//返回的数据
}
}
// 2 配置请求
xhr.open('GET','http://127.0.0.1:8080/get_person_delay') //带延迟的
xhr.responseType = 'json'
// 3 发送请求
xhr.send();
isLoading = true;
}
btn2.onclick = function(){
// 取消请求,如果数据已经回来了就取消不了了,如果来得及就会取消
xhr.abort();
}
3、jQuery封装Ajax
server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname+'/src'))
// 响应GET请求
app.get('/test_jquery_get',(request,response)=>{
console.log("有人请求test_jquery_get了",request.query);
const car = {name:'马自达', price:'25万'}
response.send(JSON.stringify(car))
});
// 响应POST请求
app.post('/test_jquery_post',(request,response)=>{
console.log("有人请求test_jquery_get了",request.body);
const car = {name:'马自达', price:'25万'}
response.send(JSON.stringify(car))
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/10_JQuery封装的ajax.html");
})
10、JQuery 封装的 ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>10_JQuery封装的ajax/title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h2 >jQuery封装的ajax</h2>
<button id="btn1">点我发送请求(JQuery-ajax-get)</button>
<button id="btn2">点我发送请求(JQuery-ajax-post)</button>
<button class="btn btn-info">通用型方法ajax</button>
<script type="text/javascript" >
const btn1=$('#btn1')
const btn2=$('#btn2')
const content=$('#content')
// 1.使用jquery发送get请求(完整版)
btn1.click(()=>{
$.ajax({
url:'http://127.0.0.1/test_jquery_get',
method:'GET',//请求类型,默认get
dataType: 'JSON',//配置相应数据格式
data:{school:'atguigu'},//携带的数据
timeout: 2000,//超时时间
// 成功的回调
success:(result,responeText,xhr)=>{
// responeText:success,error
console.log(result,responeText,xhr);
content.append(`<div>汽车名:${result.name},价格${result.price}</div>`)
},
// 失败的回调
error:(xhr)=>{ console.log('请求出错了',xhr);}
})
})
// 2.使用jquery发送get请求(精简版)
btn1.click(()=>{
$.get('http://127.0.0.1/test_jquery_get',{school:'atguigu'},(data)=>{
console.log(data);
},'json')
})
// 3.使用jquery发送post请求(完整版)
btn1.click(()=>{
$.ajax({
url:'http://127.0.0.1/test_jquery_post',
method:'POST',//请求类型,默认get
dataType: 'JSON',//配置相应数据格式
data:{school:'atguigu'},//携带的数据
timeout: 2000,//超时时间
// 成功的回调
success:(result,responeText,xhr)=>{
//responeText:success,error
console.log(result,responeText,xhr);
content.append(`<div>汽车名:${result.name},价格${result.price}</div>`)
},
// 失败的回调
error:(xhr)=>{ console.log('请求出错了',xhr);}
})
})
// 4.使用jquery发送post请求(精简版)
btn1.click(()=>{
$.post('http://127.0.0.1/test_jquery_post',{school:'atguigu'},(data)=>{
console.log(data);
},'json')
})
</script>
</body>
</html>
4、跨域
1. 同源:
如果两个页面(接口)的协议、域名、端口号都相同,我们认为他们具有相同的源
2. 同源策略:
同源策略就是浏览器的一个安全限制,它阻止了不同【域】之间进行的数据交互
3. 没有同源策略的危害:
如果没有同源策略的作用,任意站点之间可以操作资源,当你在访问一个合法网站的时候,又打开了一个恶意网站,包含了恶意脚本,恶意脚本便可以操作合法网站上的一切资源。
4. 非同源策略的限制:
1、不能获取不同源的 cookie,LocalStorage 和 indexDB
如果不同源可以获取用户的 cookie 信息等,被恶意的人加以操作,岂不是很可怕,所以这是为了防止恶意网站获取用户其他网站的 cookie 数据做出的限制。
2、不能让获取非同源的 DOM
举个栗子:如果没有这一条,恶意网站可以通过 iframe 打开银行页面,可以获取 dom 就相当于可以获取整个银行页面的信息。
3、不能发送非同源的 ajax 请求
(准确说应该是可以向非同源的服务器发起请求,但是返回的数据会被浏览器拦截)
4.1 JSONP 解决跨域(工作不用,面试常问)(手写)
1.JSONP 是什么
jsonp跨域其实也是JavaScript设计模式中的一种代理模式。在html页面中通过相应的标签从不同域名下加载静态资源文件是被浏览器允许的,所以我们可以通过这个“犯罪漏洞”来进行跨域。一般,我们可以动态的创建script标签,再去请求一个带参网址来实现跨域通信
JSONP 是一个非官方的跨域解决方法,纯粹凭借程序员的聪明才智开发出来,缺陷是只支持 get 请求。绕开xhr,借助script标签发请求
有一种前端定义函数,后端调用函数的感觉。
总结:利用script标签的src属性不受同源策略限制的特点。
server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname+'/src'))
// 响应GET请求
app.get('/test_jsonp',(request,response)=>{
//json.stringify()将JavaScript对象或值转换为JSON字符串
const person =[{name:'老刘',age:18},{name:'tom',age:20}]
//response.send(`demo(${JSON.stringify(person)})`)
const {callback} = request.query
response.send(`${callback}(${JSON.stringify(person)})`)
});
});
app.listen(8000, () => {
console.log("服务已经启动,测试地址如下:");
console.log("http://127.0.0.1:8080/13_JSONP解决跨域.html");
})
13、JSONP 解决跨域. html
btn.onclick = function(){
// 1. 创建script节点
const scriptNode = document.createElement("script");
// 2. 给节点指定src属性(请求地址)
// 把函数名也传过去
scriptNode.src = 'http://localhost:8080/test_jsonp?callback=peiqi'
// 3. 将节点放入页面
document.body.appendChild(scriptNode)
const xhr = new XMLHttpRequest();
// window.demo=(a)=>{
// 4. 准备一个函数
// 动态的函数名
window.peqi=(a)=>{
console.log(a)
}
// 5. 移除已经使用过得script节点
document.body.removeChild(scriptNode)
}
JSON 和 JSONP 的区别!
但到目前为止最被推崇或者说首选的方案还是用 JSON 来传数据,靠 JSONP 来跨域。
JSON 和 JSONP 虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON 是一种数据交换格式,而 JSONP 是一种非官方跨域数据交互协议。
jsonp 全名叫做 json with padding,很形象,就是把 json 对象用符合 js 语法的形式包裹起来以使其它网站可以请求得到,也就是将 json 数据封装成 js 文件;
json 是理想的数据交换格式,但没办法跨域直接获取,于是就将 json 包裹 (padding) 在一个合法的 js 语句中作为 js 文件传过去。这就是 json 和 jsonp 的区别,json 是想要的东西,jsonp 是达到这个目的而普遍采用的一种方法,当然最终获得和处理的还是 json。所以说 json 是目的,jsonp 只是手段。json 总会用到,而 jsonp 只有在跨域获取数据才会用到
JSONP 的缺点
1 它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求
2 它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面之间如何进行 JavaScript 调用的问题。
3 jsonp 在调用失败的时候不会返回各种 HTTP 状态码。
4 缺点是安全性。万一假如提供 jsonp 的服务存在页面注入漏洞,即它返回的 javascript 的内容被人控制的。那么结果是什么?所有调用这个 jsonp 的网站都会存在漏洞。于是无法把危险控制在一个域名下… 所以在使用 jsonp 的时候必须要保证使用的 jsonp 服务必须是安全可信的。
4.2 jQuery 封装 JSONP
const btn= $("#btn")
$("#btn").click(()=>{
$.getJSON("http://localhost:8080/test_jsonp?callback=?", {},(data)=>{
console.log(data);
});
});
4.3 CORS 解决跨域(后端技术)
设置响应头 Access-Control-Allow-Origin
server.js
app.get('/test_get', (request, response) => {
console.log("有人请求test_get了,携带的query参数是:",request.query);
// 设置响应头
// Access-Control-Allow-Origin
response.setHeader("Access-Control-Allow-Origin", "*")//任何网站都可以拿数据
//response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500")
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method", '*');
response.send("Hello_test_get");
});
app.options('/test_put', (request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*")
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method", '*');
response.send("Hello_test_get");
});
app.put('/test_put', (request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method", '*');
response.send("Hello");
});
btn.onclick = function(){
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >=200 && xhr.status<300)){
console.log(xhr.response);//返回的数据
}
}
xhr.open('GET','http://localhost:8080/test_get')
//xhr.open('PUT','http://localhost:8080/test_get')
xhr.send()
}
安装 cors
yarn add cors
server.js
// cors中间件
const cors = require('cors')
app.use(cors())
app.get('/test_get', (request, response) => {
console.log("有人请求test_get了,携带的query参数是:",request.query);
response.send("Hello_test_get");
});
cors 解决跨域
- 前端无需任何操作,靠后端完成
- 不是两个响应头就可以实现,需要一组响应头
- put、delete 不是简单请求,属于复杂请求,在真正请求之前需要进行预请求(嗅探请求)
CORS 的优缺点:
CORS 的优点:可以发任意请求
CORS 的缺点:
上是复杂请求的时候得先做个预检,再发真实的请求。发了两次请求会有性能上的损耗
5 get 和 post
GET
- 含义:从指定的资源获取数据
- 什么时候使用 GET 请求较为合适?
(1)单纯获取数据时
(2)请求非敏感数据时 - 常见的 GET 请求:
1 浏览器地址栏输入网址时,(即浏览器请求页面时,且无法手动更改)
2 可以请求外部资源的 html 标签,例如:<img><a><link><script>
且无法手动更改
3 发送 ajax 时若没有指定发送请求的方式,则使用功能 GET,或者明确指出了使用 GET 请求
4 form 表单提交时,若没有指明方式,则使用 get
POST
- 含义:想指定的资源提交要被处理的数据
- 什么时候使用 POST 请求较为合适?
(1)传送相对敏感的数据时
(2)请求的结果有持续性的副作用,例如:传递的数据要写入数据库时
备注:使用 POST 不代表绝对的安全 - 常见的 POST 请求:
1 发送 ajax 时明确指出了使用 post 方式时
2 使用第三方发送请求库时明确指出用 post 方式
3 form 表单提交时明确指出 post 方式
get 就是浏览器地址栏会有一堆 key=value&key=value…
get请求和post请求的区别:
① post比get安全 (因为post参数在请求体body中,get参数在url上面)
② get传输速度比post快 根据传参决定的。(post通过请求体传参,后台通过数据流接收。速度稍微慢一些。而get通过url传参可以直接获取)
③ post传输文件大理论没有限制 ,get传输文件大概 2-8k 之间,更加常见的是1k以内
④ get请求刷新服务器或者回退没有影响,post请求回退时会重新提交数据请求。
⑤ get请求可以被缓存,post请求不会被缓存
⑥ get请求只能进行url编码(appliacation-x-www-form-urlencoded),post请求支持多种(multipart/form-data等)。