欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

跨域请求处理

程序员文章站 2022-07-10 20:19:50
...

跨域请求是什么

一个网站的网页使用AJAX(xmlHttpRequest)访问另一个网站的请求,我们称为跨域请求。

注意事项:只有在HTTP(S)协议下,使用xmlHttpRequest对象进行AJAX远程访问时,才能称为跨域请求。所以只要通过网页发送才会出现跨域请求。如图所示:
跨域请求处理

常见的几种跨域请求:

  1. 一个网站通过JavaScript向另一个网站请求
  2. 手机基于HTML5的APP通过js向服务端api发送请求(99%)

跨域请求问题

如图所示:A网站通过ajax使用XMLHttpRequest对象向B网站发送请求,基于安全的考虑B网站的数据是无法返回到A网站的。我们把这个问题称为跨域请求问题,术语跨域资源共享问题(CORS)
跨域请求处理
--问题如图所示:
跨域请求处理

跨域问题的请求的解决方案

第一种:服务端解决策略 第二种:JSONP客户端解决方案

第一种:服务端解决策略

服务端

第一步:创建SpringBoot项目

跨域请求处理

第二步:编写pojo

@Data
public class User {
    private int userId;
    private String userName;
    private String password;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") //用于Spring,接收请求的时间数据格式
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone ="GMT+8") //用于返回JSON数据
    private Date createDate;
}

第三步:编写controller

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.zhu.rest.pojo.User;
import java.util.Date;

@RestController
@Slf4j //lombok,必须要按安装Lombok插件
public class UserController {

    /**
     * 保存用户
     * @param user
     * @return
     */
    @PostMapping(value = "/save")
    public User save(User user){
        log.debug("用户信息"+user.toString());
        user.setCreateDate(new Date());
        return user;
    }
}

第四步:配置CORS策略

--服务方编写一个MvcConfiguration放开访问策略
package com.gzsxt.springboot.configuration;

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 MvcConfiguration implements WebMvcConfigurer {
    /**
     *修改跨域请求的策略
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //addMapping表示放开所有的请求资源
        registry.addMapping("/**")
                //表示允许任何网站的远程访问,如果是指定网站的ip,则配置指定ip,*号表示任何网站
                .allowedOrigins("*")
                //表示允许跨域共享数据的请求类型
                .allowedMethods("POST","PUT","DELETE","GET")
                .allowCredentials(true)
                .maxAge(1800);
    }
}

addMapping:表示开放访问的映射路径
allowedOrigins:允许访问的IP。如果多个IP使用逗号分隔,如果允许所有IP使用星号 *
allowedMethods:表示允许跨域共享数据的请求类型
maxAge:连接的缓存的毫秒数,就是如果在这个时间内多次访问,请求参数不变,不执行后台代码,直接返回上一次的数据。
allowCredentials:访问开关,如果为false,所有的allowXXX方法失效。

客户端

第一步:创建SpringBoot项目

注意事项:需要导入JQuery、以及加入Thymeleaf依赖。
跨域请求处理

第二步:编写页面请求

--编写ajax.html请求代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="jquery.min.js" th:src="@{/jquery.min.js}"  ></script>
    <script>
        $(function () {
            $.post("http://localhost:8080/save", { userName: "John", password: "123456" },
                function(data){
                    console.log(data);
                    alert("Data Loaded: " + data);
                });
        });
    </script>
</head>
<body>
</body>
</html>

第三步:编写跳转Controller

--编写跳转到ajax的Controller类
@Controller
public class PageController {
    @RequestMapping("/ajax")
    public String ajax(){
        return "ajax";
    }
}

第二种:JSONP客户端解决方案

原理图

所有的请求使用Get方法。通过JSONP伪装返回的数据是一个回调js脚本。
跨域请求处理

调用方代码

<script type="text/javascript">
    function testajax(){
        $.ajax({
            url:"http://localhost:8081/category.json",
            type: "GET",
            dataType: "jsonp",   //jsonp请求
            jsonp:"callbackFunction",  //请求参数名
            jsonpCallback:"showData",  //回调函数名称
            success: function (data) {
                $("#text").val(JSON.stringify(data));
            }
        });
    }
</script>


服务方代码

跨域请求处理
返回的数据格式为: 回调函数名(JSON数据);