AJAX作用:
编写AjaxServlet,并使用response输出字符串 服务端代码
@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 响应数据
response.getWriter().write("hello ajax~");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
创建XmlHttpRequest对象:用于和服务器交换数据 (不用自己写,在官网复制 https://www.w3school.com.cn/js/js_ajax_http.asp )
向服务器发送请求
获取服务器响应数据
<script>
//以下 的代码都是w3school中复制来的
//1. 创建核心对象
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//2. 发送请求 路劲写全路径
xhttp.open("GET", "http://localhost:8080/ajax-demo/ajaxServlet");
xhttp.send();
//3. 获取响应
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
script>
引入axios的js文件
使用axios发送请求,应获取响应结果
<script src="js/axios-0.18.0.js">script>
<script>
//1. get
/* axios({
method:"get",
url:"http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan"
}).then(function (resp) {
alert(resp.data);
})*/
//2. post
axios({
method:"post",
url:"http://localhost:8080/ajax-demo/axiosServlet",
data:"username=zhangsan" /*设置请求参数data*/
}).then(function (resp) {
alert(resp.data);
})
script>
后台代码:
@WebServlet("/axiosServlet")
public class AxiosServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("get...");
//1. 接收请求参数
String username = request.getParameter("username");
System.out.println(username);
//2. 响应数据
response.getWriter().write("hello Axios~");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("post...");
this.doGet(request, response);
}
}
<script src="js/axios-0.18.0.js">script>
<script>
//1. get
axios.get("http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan").then(function (resp) {
alert(resp.data);
})
//2. post 方便书写 ,但是不清楚哪一个参数对应的意思
axios.post("http://localhost:8080/ajax-demo/axiosServlet","username=zhangsan").then(function (resp) {
alert(resp.data);
})
script>
Ajax:就是JavaScript 与 服务器交互的手段
有以下几点特性
Asynchronous JavaScript and XML
(异步的 JavaScript 和 XML)同步请求:(async = false)
同步请求是指当前发出请求后,浏览器什么都不能做,
必须得等到请求完成返回数据之后,才会执行后续的代码,
相当于生活中的排队,必须等待前一个人完成自己的事物,后一个人才能接着办。
也就是说,当JS代码加载到当前AJAX的时候会把页面里所有的代码停止加载,页面处于一个假死状态,
当这个AJAX执行完毕后才会继续运行其他代码页面解除假死状态
异步请求:(async = true)
默认异步:异步请求就当发出请求的同时,浏览器可以继续做任何事,
Ajax发送请求并不会影响页面的加载与用户的操作,相当于是在两条线上,各走各的,互不影响,相当于生活中的煮饭和洗菜,煮饭的过程当中可以同时进行洗菜。
一般默认值为true,异步。异步请求可以完全不影响用户的体验效果,
无论请求的时间长或者短,用户都在专心的操作页面的其他内容,并不会有等待的感觉。
缺点:
baidu.com
向 a.com
这个网站发送请求在 JS 中有内置的构造函数来创建 Ajax对象
创建 Ajax 对象以后,我们就使⽤ Ajax对象的⽅法去发送请求和接受响应
Ajax 的一个最大的特点是无需刷新页面便可向服务器传输或读写数据(又称无刷新更新页面),这一特点主要得益于 XMLHTTP
组件 XMLHTTPRequest
对象。
XMLHttpRequest 对象方法描述:
// IE9及以上
const xhr = new XMLHttpRequest()
// IE9以下
const xhr = new ActiveXObject('Mricosoft.XMLHTTP')
创建的Ajax对象 xhr 用来发送ajax请求
XMLHttpRequest 对象属性描述(用于和服务器交互数据)
//现在的浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
const xhr = new XMLHttpRequest()
// xhr 对象中的 open ⽅法是来配置请求信息的
// 第⼀个参数是本次请求的请求⽅式 get / post / put / ...
// 第⼆个参数是本次请求的 url
// 第三个参数是本次请求是否异步,默认 true 表示异步,false 表示同步
// xhr.open('请求⽅式', '请求地址', 是否异步)
xhr.open('get', './data.php')
上⾯的代码执⾏完毕以后,本次请求的基本配置信息就写完了
//如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:
const xhr = new XMLHttpRequest()
xhr.open('get', './data.php')
// 使⽤ xhr 对象中的 send ⽅法来发送请求
xhr.send()
将配置好的Ajax对象信息发送至服务端
一个最基本的 ajax 请求就是上面三步 但是光有上面的三个步骤,我们确实能把请求发送到服务端
如果服务端正常的话,响应也能回到客户端 但是我们拿不到响应
如果想要拿到响应,我们需要有两个前提条件
Ajax 状态码 :Ajax对象.readyState
用来表示一个Ajax请求的全过程中的某一个状态
主要有以下几个状态:
readyState
===
0 : 表示未初始化完成,也就是 open 方法还没有执行
readyState===
1 : 表示配置信息已经完成,也就是执行完 open 之后
readyState===
2 : 表示 send 方法已经执行完成
readyState===
3 : 表示正在解析响应内容
readyState===
4 : 表示响应内容已经解析完毕,可以在客户端使用了
由此一来,只有当readyState === 4 的时候,我们才可以正常使用服务端给我们的数据
因此,需要配合我们的HTTP状态码 (200~299)
xhr.status
(用来记录本次请求的 HTTP状态码)当readState === 4
这个条件 和HTTP 的状态码在 200~299 之间才是正常的完成本次的请求
readyStatueChange
如此一来就能用这个来监听readyStatue 是否为 4
const xhr = new XMLHttpRequest() xhr.open('get', './data.php')
xhr.send()
xhr.onreadyStateChange = function () {
// 每次 readyState 改变的时候都会触发该事件
// 我们就在这里判断 readyState 的值是不是到 4
// 并且 http 的状态码是不是 200 ~ 299
if (xhr.readyState === 4 && /^2\d{2|$/.test(xhr.status)) {
// 这里表示验证通过
// 我们就可以获取服务端给我们响应的内容了 }
}
get
、post
下面来讲解以下 get
和 post
携带参数的区别
GET请求的参数就是 在URL后面拼接
// 直接在地址后面加一个 ?,然后以 key=value 的形式传递 // 两个数据之间以 & 分割
xhr.open('get', './data.php?a=100&b=200')
xhr.send()
如此一来,服务端拿到的参数和值为a=100
b=200
post 请求的参数是携带在请求体中的,所以不需要再 url 后面拼接
const xhr = new XMLHttpRequest() xhr.open('post', './data.php')
// 如果是用 ajax 对象发送 post 请求,必须要先设置一下请求头中的 content- type
// 告诉一下服务端我给你的是一个什么样子的数据格式 xhr.setRequestHeader('content-type', 'application/x-www-form- urlencoded')
// 请求体直接再 send 的时候写在 () 里面就行
// 不需要问号,直接就是 'key=value&key=value' 的形式 xhr.send('a=100&b=200')
// 1. 创建 ajax 对象
let xhr = new XMLHttpRequest()
// 2. 配置请求信息 xhr.open(‘GET’, ‘./test.php’, true)
// 3. 发送请求 xhr.send()
// 4. 接受响应 xhr.onload = function () {
console.log(xhr.responseText) }
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<script>
/*
type 代表 请求方式
url 代表 请求url路径
data 代表 发送数据
success 代表 下载数据成功以后执行的函数
error 代表 下载数据失败以后执行的函数
*/
function $ajax({type = "get", url, data, success, error}){
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(error){
xhr = new ActiveXObject("Microsoft.XMLHTTP")
}
if(type == "get" && data){
url += "?" + querystring(data);
}
xhr.open(type, url, true);
if(type == "get"){
xhr.send();
}else{
//设置提交数据格式
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
data ? xhr.send(querystring(data)) : xhr.send();
}
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
if(success){
success(xhr.responseText);
}
}else{
if(error){
error("Error:" + xhr.status);
}
}
}
}
}
function querystring(obj){
var str = '';
for(var attr in obj){
str += attr + "=" + obj[attr] + "&";
}
return str.substring(0, str.length - 1);
}
window.onload = function(){
var aBtns = document.getElementsByTagName("button");
/*
当我们下载完数据以后需要对数据的处理方式不一样
【注】$ajax,我们需要按照传参的顺序,依次传入我们的参数。
*/
aBtns[0].onclick = function(){
$ajax({
url: "code14/1.get.php",
data: {
username: "小明",
age: 18,
password: "123abc"
},
success: function(result){
alert("GET请求到的数据:" + result);
},
error: function(msg){
alert("GET请求数据错误:" + msg);
}
})
}
aBtns[1].onclick = function(){
$ajax({
type: "post",
url: "code14/2.post.php",
data: {
username: "小花",
age: 18,
password: "123abc"
},
success: function(result){
alert("POST请求到的数据:" + result);
},
error: function(msg){
alert("POST请求数据错误:" + msg);
}
})
}
}
script>
head>
<body>
<button>GET请求button>
<button>POST请求button>
body>
html>
http协议(超文本传输协议),协议详细规定了浏览器和万维网服务器之间互相通信的规则。
请求报文:参数格式
行 GET/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
响应报文
行 HTTP/1.1 200 OK
头 Content-Type:text/html;charset=utf-8
Content-length:2048
Content-encoding:gzip
空行
体 <html>
<head>
</head>
<body>
xxx
</body>
</html>
初始化npm npm init --yes
安装express npm install express
// 1.引入express框架
const express = require('express');
// 2.创建网站服务器
const app = express();
// 3.创建路由规则
app.get('/', (request, response) => {
response.setHeader('response:', '*');
//send()
//1.send方法内部会检测响应内容的类型
//2.send方法会自动设置http状态码
//3.send方法会自动设置响应的内容类型及编码
response.send('Hello, world');
});
//监听端口
app.listen(8000,() => {
console.log('网站服务器启动成功...');
});
HTML执行代码
<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 pink;
}
</style>
</head>
<body>
<button id="btn">点击发送请求</button>
<div id="result"></div>
<script>
// 获取对象
const btn = document.querySelector("#btn");
const result = document.querySelector("#result");
btn.onclick = function() {
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化,设置请求方式和url
xhr.open('GET', 'http://localhost:9000/server');
//3.发送
xhr.send();
//4.事件绑定 处理服务器端返回的结果。当事件状态改变时进行以下操作:
xhr.onreadystatechange = function() {
//判断
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.innerHTML = xhr.response; // 将服务端发送的内容显示到div里面
}
}
}
}
</script>
</body>
服务端JS代码
//引入express框架
const express = require('express');
//创建网站服务器
const app = express();
app.get('/server', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
//send()
//1.send方法内部会检测响应内容的类型
//2.send方法会自动设置http状态码
//3.send方法会自动设置响应的内容类型及编码
res.send('Express Hello World');
});
//监听端口
app.listen(9000,()=>{
console.log('网站服务器端口:9000,启动成功');
});
xhr.open('GET', 'http://localhost:9000/server?var1=100&var2=200');
xhr.open('POST','http://127.0.0.1:9000/server');
服务端的修改为POST请求方式
app.post('/server', (req, res) => {
res.setHeader('POST response:', '*');
res.send('POST Express Hello World');
});
POST设置参数(URL参数)
xhr.send('a=100&b=200');
使用 setRequestHeader
设置请求头信息
xhr.setRequestHeader('Content-type','application/x-www-form-lencoded');
// 自定义请求头
xhr.setRequestHeader('header',' response header');
接收所有的请求方式:并设置自定义请求头
app.all('/server', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
// 响应自定义的请求头
res.setHeader('Access-Control-Allow-Header', '*');
res.send('POST Express Hello World');
});
用到的JSON的两种方法:
服务端设置:
// JSON
app.all('/jsonServer', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
// 创建JSON对象
const obj = {
name: 'kcs',
age: 21
}
// 将对象进行字符串转换
let str = JSON.stringify(obj);
// 发送响应体
res.send(str);
});
客户端设置:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONtitle>
<style>
div {
width: 200px;
height: 200px;
border: solid 2px pink;
}
style>
head>
<body>
<div>div>
<script>
// 获取元素
let divElement = document.querySelector('div');
divElement.addEventListener('mouseover', function () {
// 创建对象 const:定义常量
const xhr = new XMLHttpRequest();
// 自动转换json格式
xhr.responseType = 'json';
// 初始化URL
xhr.open('POST', 'http://127.0.0.1:9000/jsonServer');
// 发送请求
xhr.send();
// 事件绑定
xhr.onreadystatechange = function () {
// 判断状态
if (xhr.readyState === 4) {
// 响应状态
if (xhr.status >= 200 && xhr.status < 300) {
// 将数据显示在div中
divElement.innerHTML = '当前的操作者
' + '姓名:' + xhr.response.name + '
年龄:' + xhr.response.age;
}
}
}
})
script>
body>
html>
当鼠标移动到框内时就会发送请求给服务端,服务端就会将数据响应给客户端
自动重启服务端工具下载 nodemon
npm install -g nodemon
启动脚本
nodemon 脚本名称
客户端设置
<head>
<meta charset="UTF-8">
<title>超时链接</title>
<style>
div {
width: 200px;
height: 200px;
border: solid 2px pink;
}
</style>
</head>
<body>
<button>发送请求</button>
<div></div>
<script>
// 获取元素
let btnElement = document.querySelector('button');
let divElement = document.querySelector('div');
btnElement.addEventListener('click',function () {
// 创建对象 const:定义常量
const xhr = new XMLHttpRequest();
// 超时设置 2秒
xhr.timeout = 2000;
// 超时的提醒设置
xhr.ontimeout = function () {
alert('网络链接超时,请稍后重试!');
}
// 网络原因
xhr.onerror = function (e) {
alert('当前没有链接网络!');
}
// 初始化URL
xhr.open('GET','http://127.0.0.1:9000/timer');
// 发送请求
xhr.send();
// 事件绑定
xhr.onreadystatechange = function () {
// 判断状态
if (xhr.readyState === 4 ){
// 响应状态
if (xhr.status >= 200 && xhr.status < 300) {
divElement.innerHTML = xhr.response;
}
}
}
})
</script>
</body>
服务端设置接口:
// 延迟规定
app.get('/timer', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
// 延迟设置 2秒
setTimeout(() => {
res.send('REQUEST Timer Out');
},2000)
});
<head>
<meta charset="UTF-8">
<title>超时链接title>
head>
<body>
<button class="send">发送请求button>
<button class="cancel">取消请求button>
<div>div>
<script>
// 获取元素
let send = document.querySelector('.send');
let cancel = document.querySelector('.cancel');
let xhr = null;
// 发送
send.addEventListener('click', function () {
// 创建对象 const:定义常量
xhr = new XMLHttpRequest();
// 初始化URL
xhr.open('GET', 'http://127.0.0.1:9000/timer');
// 发送请求
xhr.send();
})
//取消
cancel.addEventListener('click', function () {
xhr.abort();
})
script>
body>
不断点击请求,给服务器发送相同的请求会 给服务器带来很大的压力
解决办法
<head>
<meta charset="UTF-8">
<title>重复请求</title>
</head>
<body>
<button class="send">发送请求</button>
<script>
// 获取元素
let send = document.querySelector('.send');
let xhr = null;
// 标识 是否正在发送Ajax请求
let isSending = false;
// 发送
send.addEventListener('click', function () {
// 如果前一个在发送请求就取消掉
if (isSending) {
xhr.abort();
}
// 创建对象 const:定义常量
xhr = new XMLHttpRequest();
// 正在发送修改成true
isSending = true;
// 初始化URL
xhr.open('GET', 'http://127.0.0.1:9000/server');
// 发送请求
xhr.send();
xhr.onreadystatechange = function () {
// 发送状态为 4 则修改标识
if (xhr.readyState === 4) {
isSending = false;
}
}
})
</script>
</body>
由于电脑的响应速度比较快,总之就是每次点击发送请求就会把前一个请求给取消
中文官网
服务端配置
app.get('/axios-server', (request, response) =>{
response.setHeader('Access-Control-Allow-Headers', '*');// 设置允许自定义请求头
response.setHeader('Access-Control-Allow-Origin', '*');// 设置允许跨域
response.end();
});
app.options('/axios-server', (request, response) =>{
response.setHeader('Access-Control-Allow-Headers', '*');// 设置允许自定义请求头
response.setHeader('Access-Control-Allow-Origin', '*');// 设置允许跨域
response.end();
});
app.post('/axios-server', (request, response) =>{
response.setHeader('Access-Control-Allow-Headers', '*');// 设置允许自定义请求头
response.setHeader('Access-Control-Allow-Origin', '*');// 设置允许跨域
console.log('axios-server 接口接收到请求');
response.send('HELLO Axios');
});
客户端的GET配置
<head>
<meta charset="UTF-8">
<title>Axios</title>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.1/axios.js"></script>
</head>
<body>
<button class="get">GET</button>
<button class="post">POST</button>
<button class="ajax">AJAX</button>
<script>
var get = document.querySelector('.get');
var post = document.querySelector('.post');
var ajax = document.querySelector('.ajax');
//配置baseURL
axios.defaults.baseURL = 'http://localhost:9000';
get.addEventListener('click', function () {
//get请求
axios.get('/axios-server', {
//url参数
params: {
id: 100,
vip: 7
},
// 请求头
headers: {
name: "kcs",
age: 20
}
}).then(value => {
console.log(value);
});
})
// post请求
post.onclick = function () {
//get请求
axios.post('/axios-server', {
//url参数
params: {
id: 200,
vip: 9
},
// 请求头
headers: {
name: "kcs",
age: 20
},
data: {
username: 'kcs',
password: 123456
}
})
}
// ajax请求
ajax.onclick = function () {
axios({
//请求方法
method: 'POST',
//url
url: '/axios-server',
//url参数
params: {
vip: 10,
level: 30
},
//头信息
headers: {
a: 100,
b: 200
},
//请求体参数
data: {
user: 'admin',
pass: 'admin'
}
})
}
</script>
</body>
GitHub 地址
fetch()返回的是promise对象,通过fetch()发送AJAX请求
fetch(url,[{可选配置项}])
客户端设置:
<body>
<button>AJAX</button>
<script>
const btn = document.querySelector("button");
btn.onclick = function () {
fetch('http://localhost:9000/axios-server', {
//请求方法
method: 'POST',
//url参数
params: {
vip: 10,
level: 30
},
//头信息
headers: {
a: 100,
b: 200
},
//请求体参数
data: {
user: 'admin',
pass: 'admin'
}
}).then(value => {
return value.text();
}).then(value => {
console.log(value);
})
}
</script>
</body>
服务端设置:
app.post('/axios-server', (request, response) => {
response.setHeader('Access-Control-Allow-Headers', '*');// 设置允许自定义请求头
response.setHeader('Access-Control-Allow-Origin', '*');// 设置允许跨域
console.log('axios-server 接口接收到请求');
const data = {
name: 'kcs',
age: 21
}
response.send(JSON.stringify(data));
});
同源策略是浏览器的一种安全策略
同源:协议、域名、端口号必须完全相同
违背同源策略就是跨域
AJAX请求默认遵循同源策略
客户端
<body>
<button>databutton>
<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>
服务端
//引入express框架
const express = require('express');
//创建网站服务器
const app = express();
app.get('/home', (request, response) => {
response.sendFile(__dirname + '/index.html');
});
app.all('/data', (request, response) => {
response.send('用户数据');
});
//监听端口
app.listen(8000, () => {
console.log('网站服务器端口:8000,启动成功');
});
img link iframe script
,JSONP就是利用script标签的跨域能力来发送请求的HTML创建Ajax对象:
<head>
<meta charset="UTF-8">
<title>Ajax跨域title>
<style>
.div {
width: 200px;
height: 200px;
border: solid 1px pink;
}
style>
head>
<body>
<button>发送请求button>
<div class="div">div>
<script>
// 获取对象
let buttonElement = document.querySelector('button');
let divElement = document.querySelector('div');
buttonElement.addEventListener('click',function () {
// 1. 创建对象
const x = new XMLHttpRequest();
// 2.初始化对象
x.open("GET", 'http://127.0.0.1:8000/cors-server');
// 3.发送请求
x.send()
// 绑定事件
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
divElement.innerHTML = x.response;
}
}
}
})
script>
body>
服务端设置GET请求
app.get('/cors-server', (request, response) => {
// 设置响应头
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Methods','*');
response.setHeader('Access-Control-Allow-Headers','*');
response.send('Ajax跨域解决CROS');
});
响应头首部
Access-Control-Allow-Origin
:其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求Access-Control-Expose-Headers
:在跨源访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。Access-Control-Expose-Headers 头让服务器把允许浏览器访问的头放入白名单Access-Control-Max-Age
: 头指定了preflight请求的结果能够被缓存多久Access-Control-Allow-Credentials
:头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。Access-Control-Allow-Methods
: 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。Access-Control-Allow-Headers
: 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。更多的跨域解决方案