【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第1张图片

目录

  • 引出
  • 200正常
  • 500异常--服务器异常Java代码
  • 400异常----传参相关的异常
    • get方法长度限制
    • 400异常,加了@RequestParam(value = "name") 必须传值
    • 400异常,后端类型是Integer,前端传的是string,转换失败
    • 400异常,日期格式转换失败
  • 404异常----页面找不到
  • 302重定向---地址变化
    • 【bug】302重定向,ERR_TOO_MANY_REDIRECTS,如果配置类中的,excludePathPatterns忘记加第一个反斜杠 /
  • 304---客户端有缓存
  • 405异常:服务器只能处理post,浏览器请求的是get方法
  • 网页状态码415
    • 深入理解axios的所谓的post请求:
    • 上述问题解决方案
  • 跨域问题及其解决
    • 跨域问题CROS
    • SpringBoot解决方案
      • (1)解决方案:后台允许跨域@CrossOrigin
      • (2)创建跨域类addCorsMappings
    • 在Vue中进行代理允许跨域
  • 总结

引出


网页状态码——200、302、304、400、404、405、415、500,跨域

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第2张图片

200正常

在这里插入图片描述

500异常–服务器异常Java代码

细节:null和空,null调用方法会出现空指针异常
在这里插入图片描述

400异常----传参相关的异常

get方法长度限制

在这里插入图片描述

400异常,加了@RequestParam(value = “name”) 必须传值

在这里插入图片描述

400异常,后端类型是Integer,前端传的是string,转换失败

在这里插入图片描述

400异常,日期格式转换失败

Failed to convert from type [java.lang.String] to type [java.util.Date] for value ‘2021-5-28’; nested exception is java.lang.IllegalArgumentException]

在这里插入图片描述

404异常----页面找不到

在这里插入图片描述

302重定向—地址变化

在这里插入图片描述

【bug】302重定向,ERR_TOO_MANY_REDIRECTS,如果配置类中的,excludePathPatterns忘记加第一个反斜杠 /

报错:ERR_TOO_MANY_REDIRECTS

原因:.excludePathPatterns里面的路径反斜杠没加

在这里插入图片描述

304—客户端有缓存

访问静态资源时,如果服务器认为静态文件没有变,就会返回304状态码

在这里插入图片描述

再次访问时,服务器认为自己的图片没变,所以报304

在这里插入图片描述

存在问题,如果验证码是一张图片,那浏览器清理的缓存,结果用户请求服务器的静态图片时,就拿不到了,解决方法,骗一下服务器,每次加一个?,服务器就会再次发一下

在这里插入图片描述

405异常:服务器只能处理post,浏览器请求的是get方法

在这里插入图片描述

网页状态码415

报错信息:

spring后台的报错:

Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported]

浏览器的报错:

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第3张图片

报错原因:传的是字符串,接收的时候加了@RequestBody,表示用对象接收,就报415异常

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第4张图片

解决方案:

//    public ResData queryById(@RequestBody Integer id){ // TODO:415异常
    public ResData queryById(Integer id){
// axios.post("/build/id",this.id)// TODO:415异常
axios.get("/build/id?id="+this.id)

深入理解axios的所谓的post请求:

在post请求中,通过用new URLSearchParams(),发送post请求,其实本质是以String类型的键值对发送给后端的

                let params = new URLSearchParams();
                let listParam = {"buildingIdList":this.selectedBuildingList}
                params.set("buildingList",this.selectedBuildingList)
                params.set("areaMin",this.areaMin)
                params.set("areaMax",this.areaMax)
                params.set("areaOrderASC",this.areaOrderASC)
                params.set("areaOrderDESC",this.areaOrderDESC)
                console.log(listParam)
                console.log(params)
                axios.post("/owner/query/house",params)

类型的键值对

在这里插入图片描述

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第5张图片

通常看到的表单数据是这样,

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第6张图片

本质其实就是下面这个,和get请求就差一个?,区别是一个是拼在浏览器的地址栏的路径上,另一个是放在请求头里面;

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第7张图片

所以在上面的请求中,报错了,415异常

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第8张图片

Spring后台的信息:

Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第9张图片

Using ‘application/json’, given [application/json, text/plain, /] and supported [application/json, application/+json, application/json, application/+json]

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第10张图片

这个错误通常出现在尝试使用 “application/json” 作为响应类型的API端点上。它是一个比较普遍的错误,通常是由于客户端在发送请求时没有正确设置请求头导致的。

这个错误信息的含义是,虽然该API端点支持 “application/json” 响应类型,但客户端发出的请求头中可能没有包含正确的 “Accept” 值。“Accept” 值指定了客户端能够接受的 MIME 类型。在这个例子中,客户端似乎已经将请求头中的 “Accept” 设置为 “text/plain” 或 “/”,但是服务器只支持 “application/json” 响应类型,因此会出现这个错误。

要解决这个问题,您需要确保客户端请求头中的 “Accept” 值设置为 “application/json”,或者可以同时支持多种响应类型。如果您正在使用 JavaScript 中的 XMLHttpRequest 或 Fetch API,则可以使用以下代码来设置请求头:

// 对于 XMLHttpRequest
xhr.setRequestHeader("Accept", "application/json");

// 对于 Fetch API
fetch(url, {
  headers: {
    "Accept": "application/json"
  }
});

这样设置请求头之后,应该就能够成功地获得 “application/json” 响应类型了。

上述问题解决方案

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第11张图片

这种方式会报异常!!!

    /**
     * 查询所有空闲的房子,显示到左边的框里面 TODO:后面再全查询的基础上进行
     */
    List<House> queryAllNoIntoHouse(
            @Param("buildingIdList") List<Integer> buildingIdList, // 楼栋
            @Param("storey") Integer storey, // 楼层
            @Param("areaMin") Double areaMin, // 面积
            @Param("areaMax") Double areaMax, // 面积
            @Param("areaOrderASC") Boolean areaOrderASC,
            @Param("areaOrderDESC") Boolean areaOrderDESC,// 排序
            @Param("status") Boolean... status // 如果为false,则可以查询到非空闲房子,其他情况 都是查询空闲房子

    );

SQL语句

    <select id="queryAllNoIntoHouse" resultType="house">
        SELECT
        c_house.id,
        c_owner_house.ownerId,
        c_building.num,c_building.floors,c_building.unit,
        c_house.storey,c_house.roomNum,c_house.area,c_house.into_date,c_house.status,c_house.building_id,
        user_owner.realname AS ownerName

        FROM c_house
        LEFT JOIN c_building ON c_building.id = c_house.building_id
        LEFT JOIN c_owner_house ON c_owner_house.houseId = c_house.id
        LEFT JOIN user_owner ON user_owner.id = c_owner_house.ownerId

        <where>
            <choose>
                <when test="buildingIdList!=null and buildingIdList.size()>0">
                    building_id IN
                    <foreach collection="buildingIdList" open="(" separator="," close=")" item="id">
                        #{id}
                    foreach>
                when>
                <otherwise>

                otherwise>
            choose>

            <if test="storey!=null">
                AND c_house.storey=#{storey}
            if>
            <if test="areaMin!=null">
                AND c_house.area >= #{areaMin}
            if>
            <if test="areaMax!=null">
                AND c_house.area <= #{areaMax}
            if>
            <choose>
                <when test="status!=null and status.length>0 and !status[0]">
                    
                when>
                <otherwise>
                    AND !status
                otherwise>
            choose>
        where>
        <if test="areaOrderASC">
            ORDER BY c_house.area
        if>
        <if test="areaOrderDESC">
            ORDER BY c_house.area DESC
        if>
    select>

前后端交互controller层,用专门前后端交互的实体类接收参数

// 2.处理搜索请求
    // 默认显示所有可以选择的房间,放到左侧的框里,如果选择,双击,这条数据跳到右边的框里
    @RequestMapping("/query/house")
    @ResponseBody
    public ResData queryHouse(
//            @RequestParam(value = "buildingList", defaultValue = "List[]") List buildingList, // 楼栋
//            Integer storey, // 楼层,没有用到
//            Double areaMin,
//            Double areaMax,
//            @RequestParam(value = "areaOrderASC",defaultValue = "false") Boolean areaOrderASC,
//            @RequestParam(value = "areaOrderDESC",defaultValue = "false") Boolean areaOrderDESC
            @RequestBody HouseFront houseFront
            ){
        Double areaMax = houseFront.getAreaMax();
        Double areaMin = houseFront.getAreaMin();
        Boolean areaOrderASC = houseFront.getAreaOrderASC();
        Boolean areaOrderDESC = houseFront.getAreaOrderDESC();
        Integer storey = houseFront.getStorey();
        List<Building> buildingList = houseFront.getBuildingList();
        List<Integer> buildingIds = buildingList.stream().map(Building::getId).collect(Collectors.toList());

        System.out.println("查询条件:"
                +areaMin+"/"
                +areaMax+"/"
                +buildingIds+"/"
                +storey+"/"
        );

        // 大小的问题
        if (!StringUtils.isBlank(areaMin) && !StringUtils.isBlank(areaMax)){
            if (areaMin.compareTo(areaMax)>0){
                return new ResData(1002, "最小面积不能大于最大面积", null);
            }
        }
        // 这个排序顺序不能两个都是true
        if (areaOrderASC && areaOrderDESC){
            return new ResData(1003, "排序条件冲突", null);
        }

        List<House> list = houseService.queryAllNoIntoHouse(buildingIds, storey, areaMin, areaMax, areaOrderASC, areaOrderDESC, true);
        list.forEach(System.out::println);
        return new ResData(200, "ok", list);
    }

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>新增业主</title>
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <script src="/js/jquery-3.5.1.js"></script>
    <script src="/bootstrap/js/bootstrap.js"></script>
    <script src="/js/axios.min.js"></script>
    <script src="/js/vue.min-v2.5.16.js"></script>
</head>
<body>
<div id="app">
    <br>
    录入业主基础信息:<br>
    用户名:&nbsp;&nbsp; <input type="text" v-model="username">
    真实姓名:<input type="text" v-model="realname">
    电话号码:<input type="text" v-model="tel"><br>

    身份证号:<input type="text" v-model="identity">
    性别:
    <input type="radio" v-model="gender" value="男"><input type="radio" v-model="gender" value="女"><br>
    备注信息:<textarea v-model="notes" rows="3" cols="22"></textarea><br>
    <br>
    录入选房信息:<br>
    <div>
<!--        搜索所有可以选择的房子-->
        楼栋编号:
        <select v-model="buildingId">
            <option value="">--请选择楼栋--</option>
            <option v-for="building in buildingList" :value="building.id">{{building.num}}-{{building.unit}}</option>
        </select>
        <button @click="addBuildingId">添加楼栋</button>
        <button @click="resetSelectBuildsBtn">重选楼栋</button>
        <br>

        选中的楼栋为:
        <select multiple style="width: 100px" @dbclick="removeSelectedBuildingsBtn">
            <option v-for="building in selectedBuildingList" :value="building.id">{{building.num}}-{{building.unit}}</option>
        </select>
        楼层:
        <select v-model="selectFloor">
            <option value="">-选择楼层--</option>
            <option v-for="floors in floorList" :value="floors">{{floors}}</option>
        </select>
        面积:
        <input type="text" v-model="areaMin" style="width: 50px" placeholder="小">---
        <input type="text" v-model="areaMax" style="width: 50px" placeholder="大">

        <button @click="areaASC">面积升序</button>
        <button @click="areaDESC">面积降序</button>

        <button @click="searchHouseBtn">搜索房子</button>
        <button @click="searchHouseBtnClr">重置搜索</button><br>
    </div>


<!--    TODO:可以选的房子的左侧的框-->
<!--    canSelectHouse-->
    可选的房子为:
    <select multiple style="width: 200px" @dblclick="selectHouseDbc">
        <option v-for="house in canSelectHouse" :value="house.id">
            {{house.num}}--{{house.unit}}--{{house.roomNum}}--{{house.area}}
        </option>
    </select>

    选中的房子为:
    <select  multiple style="width: 200px" @dblclick="removeSelectedHouseDbc">
        <option v-for="house in selectedHouse" :value="house.id">
            {{house.num}}--{{house.unit}}--{{house.roomNum}}--{{house.area}}平米
        </option>
    </select>
    <br>
    <button @click="add">添加</button>
    <button @click="reset">重置</button><br>
    <br>
</div>

<script>
    let app = new Vue({
        el:"#app",
        data:{
            // 首先是用户的基础信息
            username:"",
            realname:"",
            tel:"",
            gender:"男",
            identity:"",
            buildingId:"",
            houseId:"",
            notes:"",

            // 然后是查询的数据
            // 然后是选中的楼栋的id,1栋1单元...
            floorList : Array.from({ length: 12 }, (v, i) => i + 1), // 最大有12层楼,因此这里可以选择1到12
            selectedBuildingList:[], // List buildingList, // 楼栋
            selectFloor:"", // 楼层
            areaMin:"", // 面积
            areaMax:"", // 面积
            // 和排序相关的
            areaOrderASC:false,
            areaOrderDESC:false,

            // 在左侧边框里面显示可以选择的所有房间信息
            canSelectHouse:[],

            // 在右侧框里面显示已经选择的所有房间信息
            selectedHouse:[],

            buildingList:[]
        },
        methods:{
            searchHouseBtnClr(){
                // 重置搜索
                this.selectedBuildingList =[]
                this.buildingId = ""
                this.selectFloor="" // 楼层
                this.areaMin="" // 面积
                this.areaMax="" // 面积
                    // 和排序相关的
                this.areaOrderASC=false
                this.areaOrderDESC=false
                this.queryHouse();

            },
            // 如果选中了一个楼栋,就添加一个楼栋来,如果有重复的就不添加
            addBuildingId(){
                let selected = this.buildingList.find(b=>b.id===this.buildingId)
                // 这个selected是一个 building对象
                console.log(selected)
                // 只有selected里面有值,并且没有重复的时候才能添加进来
                if (selected && !this.selectedBuildingList.find(b=>b.id===selected.id)){
                    this.selectedBuildingList.push(selected)
                }
            },
            // 如果双击选中的楼栋,则删除已经选中的楼栋
            removeSelectedBuildingsBtn(event){
                const optionValue = event.target.value; // 获取双击的对象的值
                this.selectedBuildingList = this.selectedBuildingList.filter(building=>building.id != optionValue)
            },

            // 在可选的房子的框里面双击,则在选中的房子的框里面加这个房子,并且在可选的房子的框里面删除被选的房子
            selectHouseDbc(event){
                const optionValue = event.target.value; // 获取双击的对象的值
                // TODO:注意两点,这个过滤后的还是一个集合,需要获取第一个元素,另外要用== 不要用===
                const house = this.canSelectHouse.filter(house=>house.id == optionValue)[0]
                console.log(house)
                this.selectedHouse.push(house)
                this.canSelectHouse = this.canSelectHouse.filter(house=>house.id != optionValue)
                console.log(this.canSelectHouse)
                console.log(this.selectedHouse)
            },

            removeSelectedHouseDbc(event){
                const optionValue = event.target.value; // 获取双击的对象house
                console.log(optionValue)
                const house = this.selectedHouse.filter(house=>house.id == optionValue)[0]
                this.selectedHouse = this.selectedHouse.filter(house=>house.id !=optionValue)
                this.canSelectHouse.push(house)
            },

            //如果选中了一个房子,就添加一个进来,如果有重复的就不添加
            addHouseId(){
                const selectedOption = this.allhouseList.find(house=>house.id===this.houseId);

                if (selectedOption && !this.houseList.find(house => house.id === selectedOption.id)) {
                    this.houseList.push(selectedOption);
                }
            },

            removeSelectedOption(event) {
                const optionValue = event.target.value;//获取双击的对象的值
                console.log(optionValue);
                this.houseList = this.houseList.filter(house => house.id != optionValue);
            },

            add(){
                let param = {};
                param.username = this.username;
                param.realname = this.realname;
                param.tel = this.tel;
                param.gender = this.gender;
                param.identity = this.identity;
                param.notes = this.notes;
                param.houseList = this.selectedHouse;

                axios.post("/owner/add",param)
                    .then(response=>{
                        if(response.data.code==200)
                        {
                            location.href="/user/ownerPage"
                        }
                        else
                        {
                            alert(response.data.msg);
                        }
                    })


            },
            // 重新输入用户信息
            reset(){
                this.username=""
                this.realname=""
                this.tel=""
                this.identity=""
                this.notes=""
            },
            // 重新选择楼栋
            resetSelectBuildsBtn(){
                this.selectedBuildingList =[]
                this.buildingId = ""
            },
            areaASC(){
                this.areaOrderASC=true;
                this.areaOrderDESC=false;
                this.queryHouse();
            },
            areaDESC(){
                this.areaOrderASC=false;
                this.areaOrderDESC=true;
                this.queryHouse();
            },
            // 查询所有可以选择的房间
            queryHouse(){
                let jsonObj = {}
                jsonObj.buildingList=this.selectedBuildingList;
                jsonObj.storey=this.selectFloor;
                jsonObj.areaMin=this.areaMin;
                jsonObj.areaMax=this.areaMax;
                jsonObj.areaOrderASC=this.areaOrderASC;
                jsonObj.areaOrderDESC=this.areaOrderDESC;
                axios.post("/owner/query/house",jsonObj)
                    .then(response=>{
                        if (response.data.code==200){
                            this.canSelectHouse = response.data.data;
                        }else {
                            alert(response.data.msg)
                        }
                    })
            },
            searchHouseBtn(){
                this.queryHouse();
            },

        },
        mounted(){
            // 首先要获得所有可以选择的房子
            this.queryHouse();

            //查询楼栋下拉列表
            axios.get("/build/list/all")
                .then(response=>{
                    this.buildingList = response.data.data;
                })
        }
    });
</script>
</body>
</html>

专门用来前后端交互的实体类

package com.tianju.entity;

import com.alibaba.druid.filter.AutoLoad;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 专门用来和前端交互的一个对象;
 * 用于选房页面的复杂查询
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HouseFront {
    private List<Building> buildingList;
    private Integer storey;
    private Double areaMin;
    private Double areaMax;
    private Boolean areaOrderASC;
    private Boolean areaOrderDESC;
}

跨域问题及其解决

跨域问题CROS

同源策略:协议、域名(IP)、端口相同即为同源。浏览器的同源策略是一种约定,是浏览器最核心也是最基本的安全功能,如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第12张图片

跨域是指:浏览器A服务器B获取的静态资源,包括Html、Css、Js,然后在Js中通过Ajax访问C服务器的静态资源或请求。即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源。



同源策略是指: 浏览器A服务器B获取的静态资源,包括Html、Css、Js,为了用户安全,浏览器加了限制,其中的 Js通过 Ajax只能访问 B服务器的静态资源或请求。即:浏览器A从哪拿的资源,那资源中就只能访问哪。

同源是指:同一个请求协议(如:Http或Https)、同一个Ip、同一个端口,3个全部相同,即为同源。

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第13张图片

SpringBoot解决方案

(1)解决方案:后台允许跨域@CrossOrigin

要点:

  • 出现在类上,表示对所有方法上都起作用;
  • 出现在方法上,表示对方法起作用
package com.tinaju.bm.controller;

import com.tinaju.bm.dto.HttpResp;
import com.tinaju.bm.dto.ResultCode;
import com.tinaju.bm.entity.Book;
import com.tinaju.bm.service.IBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

@Api(tags = "图书的api接口类")
@RestController
@RequestMapping("/api/book")

@Slf4j
public class BookController {
    @Autowired
    private IBookService bookService;

    @ApiOperation("findPage方法测试")
    @ApiImplicitParam(name = "findByPage",value = "分页查询",required = true)
    @GetMapping("/findByPage")
    public HttpResp findByPage(int currentPage){
        List<Book> bookList = bookService.findByPage(currentPage, 5);
        return HttpResp.results(ResultCode.BOOK_SUCCESS,new Date(),bookList);

    }

    @CrossOrigin // TODO:直接在后台允许跨域
    @ApiOperation("查询所有图书接口")
    @GetMapping("/findAll")
    public HttpResp findAll(){
        long s1 = System.currentTimeMillis();
        List<Book> list = bookService.findAll();
        long s2 = System.currentTimeMillis();
        log.debug("查询耗时>>>>>>>>>>>"+(s2-s1)+"毫秒");
        return HttpResp.results(ResultCode.BOOK_SUCCESS,new Date(),list);
    }
}

(2)创建跨域类addCorsMappings

方法类 方法名称 必填 请求头字段 说明
CorsRegistry addMapping 无, 非Cors属性, 属于SpringBoot配置 配置支持跨域的路径
CorsRegistration allowedOrigins Access-Control-Allow-Origin 配置允许的源
CorsRegistration allowedMethods Access-Control-Allow-Methods 配置支持跨域请求的方法, 如:GET、POST,一次性返回
CorsRegistration maxAge Access-Control-Max-Age 配置预检请求的有效时间
CorsRegistration allowCredentials Access-Control-Allow-Credentials 配置是否允许发送Cookie, 用于 凭证请求
CorsRegistration allowedHeaders Access-Control-Request-Headers 配置允许的自定义请求头, 用于 预检请求
CorsRegistration exposedHeaders Access-Control-Expose-Headers 配置响应的头信息, 在其中可以设置其他的头信息

implements WebMvcConfigurer

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第14张图片

addCorsMappings(CorsRegistry registry)

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第15张图片

package com.tinaju.bm.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 解决跨域的问题
 */
@Configuration
public class BmWebConfig implements WebMvcConfigurer {
    // 可以不写实现类的原因是 default void configurePathMatch(PathMatchConfigurer configurer)

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**") // 所以级别下面的都允许跨域
                .allowedOrigins("*") // 允许跨域
                .allowedMethods("GET","POST","PUT","DELETE")
                .allowedHeaders("*"); // 允许头部
    }
}

在Vue中进行代理允许跨域

【总结】网页状态码——200正常、302重定向、304客户端有缓存、400浏览器请求传参异常、404未找到、405方法不允许、415不支持的媒体?、500服务器异常 & 跨域_第16张图片

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8080,
      proxy: {
        "/api": { // 1.修改端口号
          // (后端服务器地址)
          // target: 'http://124.70.138.34:10050',   // 2.配置代理服务器
          target: 'http://127.0.0.1:10050',   // 2.配置代理服务器
          changeOrigin: true, // 3.允许跨域请求
          pathRewrite: {
            // '^/api': '/' // 4.把代理路径的api删除,类似正则表达
          }
        }
      }
    }
})


总结

网页状态码——200、302、304、400、404、405、415、500,跨域

你可能感兴趣的:(Java,Front-end,java,网络安全,网络协议)