解释CORS的定义
CORS (Cross-origin resource sharing)跨域资源共享问题,是W3C的标准。
当某一资源在自己的资源服务器上的不同域或者端口请求另一个资源时,那么该资源会发起一次跨域请求. (Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.)
CORS请求介绍
CORS请求是指当前请求出现和源站不一样的请求协议、域名(含二级域名)、端口。
详细介绍哪些情况会出现跨域的情况列链接并前端的角度该如何解决问题。
CORS请求拦截
我遇到的HTTPS在CHROME浏览器出现跨域字体无法显示,在safari和HTTP的情况没有出现。
浏览器限制了发起跨站请求,存在可能是跨站请求可以正常发起,但是返回结果不包含Access-Control-Allow-Origin等符合信息就被浏览器拦截了。
目前一般很少出现浏览器主动限制CORS请求呢。
解决方案
对于简单请求,浏览器直接发出 CORS 请求。具体来说,就是由浏览器自动在头信息中增加一个 Origin 字段。然后只需要在返回的相应上加上Access-Control-Allow-Origin:[Origin]|* 。
前端详细介绍了解
接下来详细讲实际解决的情况
- 需要让内网出现线上的情况
- 按照网上解决方案去解决
- 线上CDN资源需要让其失效
内网配置出线上环境
我们内网是http协议,不支持https的协议,没有出现线上的情况。
- 先需要将线上的证书下载到本地,在上传到内网指定位置。
- 先将内网的nginx的配置文本上加上https的443的端口访问处理。(/opt/nginx/conf/conf.d)
- 证书和域名是一一对应,所有配置文件的server-name 为证书上的域名。
server { listen 443; server_name #证书上的域名即线上的网址 access_log #日志地址 ssl on; ssl_certificate #证书地址 ssl_certificate_key #证书地址 location ~ / { proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header FORWARDED-FOR $remote_addr; proxy_pass #代理到Tomcat的服务器的域名+端口 include conf.d/proxy_params;}}
1.遇到问题只能通过线上域名访问,但是无法访问到内网的资源。
2.DNS 服务详细了解
先了解客户端进行域名解析的流程:
先查hosts文件
若没有,查本地DNS缓存
若没有,再查DNS服务器:
先查DNS服务器的本地DNS缓存
若没有,再查DNS服务器的解析库
都没有,那DNS向根域发起请求,开始迭代查询
如果缓存的有效期为1天的话,能极大减轻DNS服务器的压力,所以对于DNS的架构,“缓存”是很重要的。
3.在/etc/hosts文件加上ip和域名的强制映射(内网ip(nginx) 线上域名)。我们的nginx和tomcat服务器是在同一个服务器上。 接下来线上域名的访问都会转接到内网资源的访问。(另一个办法:通过Charles进行代理实现)
4.详细分析后,字体是加载进来的js代码发起的静态资源访问(CORS的访问,二级域名不一样)。折腾好久才想起来的,但是静态资源的访问是通过不同内外网环境进行变化的,内网静态资源都在内网服务器上,外网的静态资源在CDN缓存上和静态资源服务器上。
5.将加载js的代码写死,变成直接访问外网的静态资源。(与线上保持一致)
6.静态资源访问需要变成内网资源的访问。同样,先在hosts文件加上ip和静态资源的域名的强制映射(内网ip 线上域名)。
内网静态资源nginx配置
server { listen 443; server_name #静态资源服务器 gzip on; ssl on; ssl_certificate /data/config/ssl/star.enjoymeet.com.chained; ssl_certificate_key #证书地址 access_log #证书地址 location ~* \.(eot|ttf|woff|woff2)$ { add_header Access-Control-Allow-Origin * ; add_header Access-Control-Allow-Methods GET; proxy_pass #代理到Tomcat的服务器的域名+端口 } }
基本上实现在内网测试。
参考资料:在nginx上解决问题
Nginx通过CORS实现跨域1
Nginx通過CORS實現跨域2
HTTP访问控制(CORS)
How do I add Access-Control-Allow-Origin in NGINX?
线上处理
- CDN 回源,我们回源的访问80端口欧,HTTP协议。
- CDN的资源让线上的资源失效。