门户网站建设 突出服务,学习电子商务网站建设与管理的收获,企业为什么需要建站,天津网站制作公司电话1、AJAX 简介
AJAX 全称为 Asynchronous JavaScript And XML#xff08;中文名#xff1a;阿贾克斯#xff09;#xff0c;就是异步的 JS 和 XML。AJAX 不是新的编程语言#xff0c;而是一种将现有的标准组合在一起使用的新方式。AJAX 可以在浏览器中向服务器发送异步请求…1、AJAX 简介
AJAX 全称为 Asynchronous JavaScript And XML中文名阿贾克斯就是异步的 JS 和 XML。AJAX 不是新的编程语言而是一种将现有的标准组合在一起使用的新方式。AJAX 可以在浏览器中向服务器发送异步请求最大的优势无刷新获取数据。AJAX 的两个主要功能使您可以执行以下操作 向服务器发出请求而无需重新加载页面 从服务器接收和处理数据
2、AJAX 的优缺点
2.1 AJAX 的优点
可以无需刷新页面而与服务器端进行通信。 允许你根据用户事件来更新部分页面内容。 2.2 AJAX 的缺点
没有浏览历史不能回退。存在跨域问题同源。出于安全原因浏览器不允许跨域访问。也就是当前网页和 AJAX 要请求的网页地址要在同一个域名下。 SEO搜索引擎优化 不友好。因为源代码没有具体信息而是通过 AJAX 异步获取数据无法被爬虫获取到数据 3、AJAX 的工作原理
JavaScript 使用一个 XMLHttpRequest核心对象 对象向服务器发出 HTTP 请求并作为响应接收数据。所有现代浏览器ChromeFirefoxIE7 SafariOpera都支持该 XMLHttpRequest 对象。 具体步骤 网页中发生了一个事件即页面已加载或单击了某些按钮 JavaScript 创建 XMLHttpRequest 对象 XMLHttpRequest 对象将请求发送到 Web 服务器 服务器处理请求 服务器将响应发送回网页 响应由 JavaScript 读取 JavaScript 更新 HTML DOM 4、温习 HTTP 协议
HTTPHypertext Transport Protocol超文本传输协议详细规定了浏览器和万维网服务器之间互相通信的规则。主要包括请求报文、响应报文。我们温习一下它们的格式与参数
4.1 请求报文
请求行主要包括请求类型GET、POST使用居多、URL 路径、协议版本一般是 HTTP/ 1.1请求头主要包括 Host、Cookie、Content-Type、User-Agent都是键值对形式空行空行固定请求体GET 类型的请求体是空的POST 类型的请求体可以为空也可以不为空 4.2 响应报文 响应行主要包括协议版本HTTP/1.1、响应状态码比如200、404、500、响应字符串比如 OK响应头Content-Typetext/html;charsetutf-8、Content-length、Content-encoding空行空行固定响应体服务端返回的具体响应数据日常开发用得最多的内容 5、后台服务应用准备
要学习 AJAX 需要后台服务这里我们以熟悉的 Java 为例。在企业开发中目前大多数还是 Java 后台。这里要求对 Java 有一定的了解并且把 JDK 环境、Maven 环境、IDEA 环境都准备好。
代码结构比较简单如截图 pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.study/groupIdartifactIdAjax/artifactIdversion1.0-SNAPSHOT/version!-- SpringBoot 版本 --parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.3.12.RELEASE/version/parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency!--web支持--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency/dependencies/project
application.yml 此配置非必须如果不配置服务器端口号默认 8080
# 配置服务器端口号
server:port: 8000
AjaxApp
package com.study;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** author CSDN 流放深圳* description 主应用程序* signature 让天下没有难写的代码* create 2024-03-24 下午 4:03*/
SpringBootApplication
public class AjaxApp {public static void main(String[] args) {SpringApplication.run(AjaxApp.class, args);}
}AjaxController
package com.study.controller;import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;/*** author CSDN 流放深圳* description* signature 让天下没有难写的代码* create 2024-03-24 下午 4:05*/
RestController
public class AjaxController {/*** Get 请求* return*/GetMapping(/helloWorld)public String helloWorld(){String result Hello,Ajax!欢迎来到新的学习基地;return result;}/*** Post 请求* return*/PostMapping(/say)public String say(){String result 纸上得来终觉浅绝知此事要躬行;return result;}/*** 根据 id 获取信息* param id* return*/GetMapping(/getById)public MapString, String getById(RequestParam Integer id) {MapString, String map new HashMap();if(id 1){map.put(userName, 刘德华);map.put(introduction, 我是1号选手我来自香港);}else if(id 2){map.put(userName, 周杰伦);map.put(introduction, 我是2号选手我来自台湾);try{Thread.sleep(3000);//模拟超时3秒后响应接口}catch (Exception e){System.out.println(3秒后响应接口请求);}}return map;}/*** 根据 userName 获取数据* param userName* return*/PostMapping(/getByName)public MapString, String getByName(RequestParam String userName) {MapString, String map new HashMap();if(周星驰.equals(userName)){map.put(userName, 周星驰);map.put(introduction, 曾经有一份真挚的爱情摆在我面前我没有珍惜等我失去的时候我才后悔莫及人世间最痛苦的事莫过于此。如果上天能够给我一个再来一次的机会我会对那个女孩子说三个字我爱你。如果非要在这份爱上加上一个期限我希望是一万年。);}else if(海明威.equals(userName)){map.put(userName, 海明威);map.put(introduction, 海的爱太深时间太浅);}return map;}}CorsConfig注意这个配置类在前期学习必须要加上否则会有跨域问题
package com.study.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** author CSDN 流放深圳* description 跨域处理配置类* signature 让天下没有难写的代码* create 2024-03-24 下午 4:15*/
Configuration
public class CorsConfig implements WebMvcConfigurer {/*** 允许跨域配置* param registry*/Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**)//匹配所有的请求.allowedOrigins(*)//允许访问的客户端所有的域名.allowedMethods(GET, POST, HEAD, PUT, DELETE, OPTIONS)//允许列出的请求方式其实就是标准的 HTTP 协议的请求方式.allowCredentials(true)//允许请求带有验证信息.maxAge(3600).allowedHeaders(*);//允许客户端所有的请求头}
}如果不加这个跨域处理配置类会出现如下错误 Access to XMLHttpRequest at http://127.0.0.1:8000/helloWorld from origin http://127.0.0.1:5500 has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource. OK后台基础环境搭建完毕。启动后台服务测试http://127.0.0.1:8000/helloWorld 6、JavaScript 原生 AJAX
6.1 AJAX 入门
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleJavaScript 原生 AJAX/titlescriptwindow.onload function(){//文档加载完成后执行//获取文本域元素let textarea document.getElementById(textarea);//需求1点击按钮1通过 GET 请求获取数据let btn1 document.getElementById(btn1);//绑定按钮1事件btn1.onclick function(){//1.创建 XMLHttpRequest 对象let xhr new XMLHttpRequest();//2.初始化设置请求方式和 urlxhr.open(GET, http://127.0.0.1:8000/helloWorld);//设置请求头信息可以设置自定义请求头信息//xhr.setRequestHeader(Content-Type,text/plain;charsetUTF-8);xhr.setRequestHeader(token,token123);//自定义会话的 token//3.发送请求xhr.send();//4.事件绑定处理服务器返回的结果。readyState 是 xhr 对象中的属性表示状态有0、1、2、3、4xhr.onreadystatechange function(){if(xhr.readyState 4){//判断响应状态码一般200开头的都是成功/*xhr.status响应状态码xhr.statusText状态字符串xhr.getAllResponseHeaders()所有响应头xhr.response响应体*/if(xhr.status 200 xhr.status 300){//设置 textarea 的文本textarea.innerHTML xhr.response;}}}}//需求2点击按钮2通过 POST 请求获取数据let btn2 document.getElementById(btn2);btn2.onclick function(){let xhr new XMLHttpRequest();xhr.open(POST, http://127.0.0.1:8000/say);xhr.send();xhr.onreadystatechange function(){if(xhr.status 200 xhr.status 300){//设置 textarea 的文本textarea.innerHTML xhr.response;}}}}/script
/head
bodybutton idbtn1按钮1 通过 GET 请求获取数据/buttonbutton idbtn2按钮2 通过 POST 请求获取数据/buttonbrbrtextarea idtextarea cols30 rows10/textarea
/body
/html
效果分别点击2个按钮在文本框看到后台服务器返回的数据。 另外我们设置的自定义请求头信息也可以在浏览器中看到 关于XMLHttpRequest 对象的 readyState 状态枚举值
XMLHttpRequest.readyState - Web API 接口参考 | MDN
值状态描述0UNSENT代理被创建但尚未调用 open() 方法。1OPENEDopen() 方法已经被调用。2HEADERS_RECEIVEDsend() 方法已经被调用并且头部和状态已经可获得。3LOADING下载中responseText 属性已经包含部分数据。4DONE下载操作已完成或者已经失败。 6.2 处理 JSON 数据
JSON 格式的数据已经成为企业级开发首选、必选的数据格式之一。因此掌握 JSON 格式的数据极其重要。
处理 JSON 格式有2种方式 方式1 设置 XMLHttpRequest 对象的返回体数据类型为 jsonxhr.responseType json;自动转换。如const userName xhr.response.userName; 方式2手动对数据进行处理 let serverData JSON.parse(xhr.response); const userName serverData.userName; !DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title处理JSON数据/titlescriptwindow.onload function(){//文档加载完成后执行//获取文本域元素let textarea document.getElementById(textarea);//需求1点击按钮1通过 GET 请求获取数据let btn1 document.getElementById(btn1);//绑定按钮1事件btn1.onclick function(){//1.创建 XMLHttpRequest 对象let xhr new XMLHttpRequest();//设置响应体数据的类型xhr.responseType json;//2.初始化设置请求方式和 urlxhr.open(GET, http://127.0.0.1:8000/getById?id1);//3.发送请求xhr.send();//4.事件绑定处理服务器返回的结果。readyState 是 xhr 对象中的属性表示状态有0、1、2、3、4xhr.onreadystatechange function(){if(xhr.readyState 4){if(xhr.status 200 xhr.status 300){//方式1手动对数据进行转换/*let serverData JSON.parse(xhr.response);const userName serverData.userName;const introduction serverData.introduction;textarea.innerHTML 用户名 userName自我介绍 introduction;*/// 方式2设置响应体数据类型然后自动转换const userName xhr.response.userName;const introduction xhr.response.introduction;textarea.innerHTML 用户名 userName自我介绍 introduction;}}}}}/script
/head
bodybutton idbtn1GET 获取JSON数据/buttonbrbrtextarea idtextarea cols30 rows10/textarea
/body
/html
效果 6.3 解决 IE 浏览器缓存问题
问什么是 IE 浏览器缓存问题 答IE 浏览器在处理 AJAX 请求时会优先从本地判断是否有缓存如果有则不再向后台服务器获取数据而是直接读取本地缓存数据。这对一些实时性要求高的场景来说显然是不合理的。 问如何解决 IE 浏览器缓存问题 答在请求头的 url 参数后面增加一个当前时间戳的参数传递到后台保证每次请求都是新的请求。 如xhr.open(GET, http://127.0.0.1:8000/getById?id1tnew Date()); 6.4 处理请求超时和网络异常
一个良好的系统都会有超时和网络异常的处理给用户带来更好的体验否则让用户一直干等显然是不合理。那么 AJAX 是如何处理请求超时和网络异常的呢
6.4.1 处理请求超时 //设置超时时间2秒 xhr.timeout 2000; //超时回调函数 xhr.ontimeout function(){ textarea.innerHTML 啊噢超时了请您去别的地方逛逛吧; } 6.4.2 处理网络异常 //网络异常回调 xhr.onerror function(){ textarea.innerHTML Sorry网络异常请您稍后重试; } 注意代码修改了获取的 id2后台有设置线程3秒后响应请求
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title处理超时和网络异常/titlescriptwindow.onload function(){//文档加载完成后执行//获取文本域元素let textarea document.getElementById(textarea);//需求1点击按钮1通过 GET 请求获取数据let btn1 document.getElementById(btn1);//绑定按钮1事件btn1.onclick function(){//1.创建 XMLHttpRequest 对象let xhr new XMLHttpRequest();//设置响应体数据的类型xhr.responseType json;//设置超时时间2秒xhr.timeout 2000;//超时回调函数xhr.ontimeout function(){textarea.innerHTML 啊噢超时了请您去别的地方逛逛吧;}//网络异常回调xhr.onerror function(){textarea.innerHTML Sorry网络异常请您稍后重试;}//2.初始化设置请求方式和 urlxhr.open(GET, http://127.0.0.1:8000/getById?id2);//3.发送请求xhr.send();//4.事件绑定处理服务器返回的结果。readyState 是 xhr 对象中的属性表示状态有0、1、2、3、4xhr.onreadystatechange function(){if(xhr.readyState 4){if(xhr.status 200 xhr.status 300){const userName xhr.response.userName;const introduction xhr.response.introduction;textarea.innerHTML 用户名 userName自我介绍 introduction;}}}}}/script
/head
bodybutton idbtn1GET 获取JSON数据/buttonbrbrtextarea idtextarea cols30 rows10/textarea
/body
/html
测试请求超时 测试网络异常把自己的浏览器的【网络】设置离线模式 6.5 取消请求
使用 XMLHttpRequest 对象的 abort() 函数可以手动取消请求。 xhr.send(); xhr.abort();//取消请求 textarea.innerHTML 取消了请求; 6.6 重复请求问题
问什么是 AJAX 重复请求问题 答指的是同一个浏览器在某一段时间内发送了多次请求且前几次的请求都失败了这样会对后台服务器的压力是很大的特别是并发量大的系统。因此需要处理重复请求的问题。 处理重复请求问题可以按照如下步骤
创建一个标识变量判断是否正在发送请求。如果判断该变量正在发送请求则取消并且重新创建一个新的请求。如果请求发送成功且返回数据成功修改标识变量的值。
!DOCTYPE html
html langzh-CN
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title重复请求问题/titlescriptwindow.onload function(){//文档加载完成后执行//获取文本域元素let textarea document.getElementById(textarea);//需求1点击按钮1通过 GET 请求获取数据let btn1 document.getElementById(btn1);//创建标识变量let isSending false;//绑定按钮1事件btn1.onclick function(){//1.创建 XMLHttpRequest 对象let xhr new XMLHttpRequest();//判断标识变量if(isSending){xhr.abort();//取消请求} else {isSending true;//设置为正在请求}//设置响应体数据的类型xhr.responseType json;//设置超时时间5秒xhr.timeout 5000;//超时回调函数xhr.ontimeout function() {textarea.innerHTML 啊噢超时了请您去别的地方逛逛吧;}//网络异常回调xhr.onerror function(){textarea.innerHTML Sorry网络异常请您稍后重试;}//2.初始化设置请求方式和 urlxhr.open(GET, http://127.0.0.1:8000/getById?id2);//3.发送请求xhr.send();//4.事件绑定处理服务器返回的结果。readyState 是 xhr 对象中的属性表示状态有0、1、2、3、4xhr.onreadystatechange function(){if(xhr.readyState 4){//返回数据成功后修改变量表示isSending false;if(xhr.status 200 xhr.status 300){const userName xhr.response.userName;const introduction xhr.response.introduction;textarea.innerHTML 用户名 userName自我介绍 introduction;}}}}}/script
/head
bodybutton idbtn1GET 获取JSON数据/buttonbrbrtextarea idtextarea cols30 rows10/textarea
/body
/html 效果多次快速点击发送请求后台服务器只接收到了第一个请求并返回数据其它请求均被取消。 7、jQuery 发送 AJAX 请求
jQuery 发送 AJAX 请求主要有 3 个常用方法
$.get()$.post()$.ajax() 其中$.get() 和 $.post() 都是简单的请求方式有 4 个参数url,[data],[callback],[type] url请求的 url 地址 data参数值键值对格式 callback成功时的回调函数 type返回的数据格式xml, html, script, json, text, _default $.ajax() 用于处理比较复杂的请求它可以设置很多参数比如头部信息headers注意值不允许包含中文或者说是全角输入法的内容、成功的回调success、失败的回调error、超时设置timeout等 !DOCTYPE html
html langzh-CNheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titlejQuery 发送 AJAX/title!-- 通过 CDN 引入 js库 --script srchttps://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js/scriptscript$(function () {//文档加载完成后执行//发送 get 请求$(#btn1).click(function () {//get 请求有4个参数url、参数键值对、回调函数、返回的数据类型$.get(http://127.0.0.1:8000/getById, { id: 1 }, function (data) {const userName data.userName;const introduction data.introduction;//在文本域中显示信息$(#textarea).val(用户名 userName 自我介绍 introduction);}, json);});//发送 post 请求$(#btn2).click(function () {//post 请求也有4个参数url、参数键值对、回调函数、返回的数据类型$.post(http://127.0.0.1:8000/getByName, { userName: 周星驰 }, function (data) {const userName data.userName;const introduction data.introduction;//在文本域中显示信息$(#textarea).val(用户名 userName 自我介绍 introduction);}, json);});//发送 ajax 请求。语法jQuery.ajax(url,[settings])$(#btn3).click(function () {const myToken your token message;const otherHeader can no be Chinese!;$.ajax({//url 地址url: http://127.0.0.1:8000/getByName,//请求类型type: POST,//头部信息值不允许包含中文headers: {token: myToken,other: otherHeader},//参数data: { userName: 海明威 },//响应体结果dataType: json,//成功的回调success: function (data) {const userName data.userName;const introduction data.introduction;//在文本域中显示信息$(#textarea).val(用户名 userName 自我介绍 introduction);},//失败的回调error: function () {$(#textarea).val(接口调用失败啦);},//超时时间设置单位毫秒timeout: 2000,})});})/script
/headbodyh2jQuery 发送 AJAX 请求/h2button idbtn1GET 请求/buttonbutton idbtn2POST 请求/buttonbutton idbtn3通用型方法 ajax/buttonbrbrtextarea idtextarea cols30 rows10/textarea
/body/html
效果 8、axios 发送 AJAX 请求
axios 是现在前端比较流行和热门的 AJAX 工具库也是 VUE 和 React 推荐的发送 AJAX 请求的工具包。关于 axios 后续博客会继续迭代。
axios 发送 AJAX 请求主要有 3 个常用方法与 jQuery 类似
axios.get()axios.post()axios() axios 在调用 AJAX 有一个 then() 函数用来接收返回数据 !DOCTYPE html
html langzh-CNheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleaxios 发送 AJAX/title!-- 通过 CDN 引入 js库 --script srchttps://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js/scriptscriptwindow.onload function () {//文档加载完成后执行//获取文本域元素let textarea document.getElementById(textarea);//获取按钮let btn1 document.getElementById(btn1);let btn2 document.getElementById(btn2);let btn3 document.getElementById(btn3);//配置 axios 基础请求路径axios.defaults.baseURL http://127.0.0.1:8000;//发送 get 请求btn1.onclick function () {axios.get(/getById,//参数{params: {id: 1},//请求头信息headers: {token: your token}}).then(response {//响应状态码console.log(response.status);//响应状态字符串console.log(response.statusText);//响应头信息console.log(response.headers);//响应体console.log(response.data);//在文本域显示信息const userName response.data.userName;const introduction response.data.introduction;textarea.innerHTML 用户名 userName 自我介绍 introduction;}).catch(function (error) {console.log(error);});};//发送 post 请求btn2.onclick function () {axios.post(/getByName,//请求体参数{userName: 周星驰},//其它参数{params: {otherParam: other},//请求头参数headers: {//注意后台服务该 POST 方法获取 userName 参数的格式是RequestParam String userName需要增加头部 Content-Type 的配置Content-Type: application/x-www-form-urlencoded;charsetutf-8,token: your token}}).then(function (response) {//响应状态码console.log(response.status);//响应状态字符串console.log(response.statusText);//响应头信息console.log(response.headers);//响应体console.log(response.data);//在文本域显示信息const userName response.data.userName;const introduction response.data.introduction;textarea.innerHTML 用户名 userName 自我介绍 introduction;}).catch(function (error) {console.log(error);});};//发送 axios 请求btn3.onclick function () {axios({//请求方法method: POST,//urlurl: /getByName,//url参数params: {otherParam: other},//头信息headers: {//注意后台服务该 POST 方法获取 userName 参数的格式是RequestParam String userName需要增加头部 Content-Type 的配置Content-Type: application/x-www-form-urlencoded;charsetutf-8,token: your token},//请求体参数data: {userName: 海明威}}).then(response {//响应状态码console.log(response.status);//响应状态字符串console.log(response.statusText);//响应头信息console.log(response.headers);//响应体console.log(response.data);//在文本域显示信息const userName response.data.userName;const introduction response.data.introduction;textarea.innerHTML 用户名 userName 自我介绍 introduction;}).catch(function (error) {console.log(error);});}}/script
/headbodyh2axios 发送 AJAX 请求/h2button idbtn1GET 请求/buttonbutton idbtn2POST 请求/buttonbutton idbtn3通用型方法 axios/buttonbrbrtextarea idtextarea cols30 rows10/textarea
/body/html
需要注意的是后台服务接收 POST 请求使用的方式是 RequestParam String userName因此需要在 POST 请求的头部增加以下信息 Content-Type: application/x-www-form-urlencoded;charsetutf-8 否则会报错 AxiosError {message: Request failed with status code 400, name: AxiosError, code: ERR_BAD_REQUEST, config: {…}, request: XMLHttpRequest, …} 效果 9、跨域以及处理办法
9.1 什么是跨域 当一个请求 url 的协议、域名、端口号三者之间任意一个与当前页面 url 不同即为跨域。 跨域也叫未被了“同源策略”何为“同源”即协议、域名、端口号 必须完全相同。 9.2 如何解决跨域问题
9.2.1 前端解决方案 —— JSONP
1、JSONP 是什么 JSONP(JSON with Padding)是一个非官方的跨域解决方案纯粹凭借程序员的聪明才智开发出来只支持 get 请求。 2、JSONP 怎么工作的 在网页有一些标签天生具有跨域能力比如img、link、iframe、script。JSONP 就是利用 script 标签的跨域能力来发送请求的。 3、JSONP 的使用 1、动态的创建一个 script 标签如 var script document.createElement(script); 2、设置 script 的 src设置回调函数如 script.src http://localhost:8000/yourAPI?callbackabc;
function abc(data) {alert(data.name);
}; 3、将 script 添加到 body 中 document.body.appendChild(script); 4、服务器中路由的处理 router.get(/yourAPI , function (req , res) {console.log(收到请求);var callback req.query.callback;var obj {name:马云, world:让天下没有难做的生意}res.send(callback(JSON.stringify(obj)));
}); 9.2.2 后台服务解决方案 —— 跨源资源共享CORS
9.2.2.1 CORS 是什么
CORSCross-Origin Resource Sharing跨域资源共享。CORS 是官方的跨域解决方案它的特点是不需要在客户端做任何特殊的操作完全在服务器中进行处理支持 get 和 post 和其它标准的 HTTP 请求。跨域资源共享标准新增了一组 HTTP 首部字段允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
官网跨源资源共享CORS - HTTP | MDN
9.2.2.2 CORS 怎么工作的
CORS 是通过设置一个响应头来告诉浏览器该请求允许跨域浏览器收到该响应以后就会对响应放行。
92.2.3 CORS 的使用
方式1如果后台服务是 Java 语言写的可以加上这个配置类全局生效
package com.study.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** author CSDN 流放深圳* description 跨域处理配置类* signature 让天下没有难写的代码* create 2024-03-24 下午 4:15*/
Configuration
public class CorsConfig implements WebMvcConfigurer {/*** 允许跨域配置* param registry*/Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**)//匹配所有的请求.allowedOrigins(*)//允许访问的客户端所有的域名.allowedMethods(GET, POST, HEAD, PUT, DELETE, OPTIONS)//允许列出的请求方式其实就是标准的 HTTP 协议的请求方式.allowCredentials(true)//允许请求带有验证信息.maxAge(3600).allowedHeaders(*);//允许客户端所有的请求头}
}方式2增加自定义过滤器全局生效
package com.study.config;import org.springframework.context.annotation.Configuration;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** author CSDN 流放深圳* description 自定义跨域过滤器* create 2024-03-24 下午 6:15* since 1.0.0*/
Configuration
public class CorsFilter implements Filter {Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response (HttpServletResponse) servletResponse;response.setHeader(Access-Control-Allow-Origin, *);response.setHeader(Access-Control-Allow-Methods, GET, POST, PUT, HEAD, OPTIONS, DELETE);response.setHeader(Access-Control-Max-Age, 3600);response.setHeader(Access-Control-Allow-Headers, x-requested-with);response.setHeader(Access-Control-Expose-Headers, content-disposition);filterChain.doFilter(servletRequest, servletResponse);}Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}Overridepublic void destroy() {Filter.super.destroy();}
}方式3在某个 Controller 类或者方法上加注解 CrossOrigin
比如 如果在类上加这个注解表示这个类所有的方法都允许跨域如果只在某个方法上加这个注解表示只有该方法允许跨域。