Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 435|回复: 0

Access-Control-Allow-Origin 跨域问题 SpringMVC解决 与 前端JS Webpack解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-9 14:58:48 | 显示全部楼层 |阅读模式

     

     

     

    跨域问题 是针对ajax的一种限制

    跨域:浏览器对于JS的同源策略的限制。

    以下情况都属于跨域:

    域名不同                       如: www.jd.com   www.taobao.com

    域名相同,端口不同       如: www.taobao.com:8081  www.taobao.com:8082

    二级域名不同               如: 3c.tmall.com   chaoshi.tmall.com 

    http和https也属于跨域

     

    解决跨域问题的方案

    目前比较常用的跨域解决方案有3种:

    • Jsonp

      最早的解决方案,利用script标签可以跨域的原理实现。  限制:需要服务的支持 ;  只能发起GET请求

    • nginx反向代理

      思路是:利用nginx把跨域反向代理为不跨域,支持各种请求方式   缺点:需要在nginx进行额外配置,语义不清晰

    • CORS

      规范化的跨域请求解决方案,安全可靠。

      优势:在服务端进行控制是否允许跨域,可自定义规则 ;   支持各种请求方式

      缺点: 会产生额外的请求

     

    *****因为我们将采用CORS的方式解决,故重点介绍一下它如何来处理!!!*****

       

        CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)

    它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

    CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

    • 浏览器端:目前,所有浏览器都支持该功能(IE10以下不行)。整个CORS通信过程,都是浏览器自动完成,不需要用户参与

    • 服务端:CORS通信与AJAX没有任何差别,因此你不需要改变以前的业务逻辑。浏览器会在请求中携带一些头信息,我们需要以此判断是否允许其跨域,然后在响应头中加入一些信息即可。这一般通过过滤器完成即可。

     

    浏览器会将ajax请求分为两类,其处理方案略有差异:简单请求、特殊请求

    简单请求

    只要同时满足以下两大条件,就属于简单请求。:

    (1) 请求方法是以下三种方法之一:HEAD  GET  POST

    (2)HTTP的头信息不超出以下几种字段: Accept  Accept-Language  Content-Language  Last-Event-ID  Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

    当浏览器发现发起的ajax请求是简单请求时,会在请求头中携带一个字段:Origin

     

    Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。

    如果服务器允许跨域,需要在返回的响应头中携带下面信息:

    Access-Control-Allow-Origin: http://yangw.com
    Access-Control-Allow-Credentials: true
    Content-Type: text/html; charset=utf-8

     

    Access-Control-Allow-Origin:可接受的域,是一个具体域名或者*(代表任意域名)

    Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true

    要想操作cookie,需要满足3个条件:

          服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。

          浏览器发起ajax需要指定withCredentials 为true

          响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名

     

    特殊请求

    不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT

    特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

    浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

    与简单请求相比,除了Origin以外,多了两个头:

     

    Access-Control-Request-Method:  接下来会用到的请求方式,比如PUT

    Access-Control-Request-Headers:  会额外用到的头信息

    Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了(让它默认,不用处理)

     

    我们只要解决了复杂清醒,简单情形自然包含了!

    解决方式1:后端JAVA

    我们用Java框架SpringMVC实现: 由于我这里是一个Spring Cloud项目,故写了个过滤器放在了网关里面统一处理

     

    解决方式2--只在前端webpack-dev-server

    webpack配置中主要的参数说明

    2.1 ‘/api’
    捕获API的标志,如果API中有这个字符串,那么就开始匹配代理,
    比如API请求/api/users, 会被代理到请求 http://www.baidu.com/api/users 。

    2.2 target
    代理的API地址,就是需要跨域的API地址。
    地址可以是域名,如:http://www.baidu.com
    也可以是IP地址:http://127.0.0.1:3000
    如果是域名需要额外添加一个参数changeOrigin: true,否则会代理失败。

    2.3 pathRewrite
    路径重写,也就是说会修改最终请求的API路径。
    比如访问的API路径:/api/users,
    设置pathRewrite: {’^/api’ : ‘’},后,
    最终代理访问的路径:http://www.baidu.com/users,
    这个参数的目的是给代理命名后,在访问时把命名删除掉。

    2.4 changeOrigin
    这个参数可以让target参数是域名。

    2.5 secure
    secure: false,不检查安全问题。
    设置后,可以接受运行在 HTTPS 上,可以使用无效证书的后端服务器

    2.6 其他参数配置查看http-proxy-middleware文档
    其他的配置参数等信息,可以查看这里:https://github.com/chimurai/h…

     

    *********************以上两种解决方式任选其一均可**************

     

     

     关于环境,我还在hosts中配置了域名映射,使用了nginx帮我反向代理

    可以参考我上一篇博文  https://www.cnblogs.com/yangw/p/11947752.html

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-1 05:55 , Processed in 0.061107 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表