老生常谈的跨域问题

437 阅读4分钟

又到了一年一度的面试季了。复习一下开发中常见的跨域

什么是跨域

我们先来了解一下,什么是跨域 ?
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 实施的安全限制。 当一个请求 url 的 协议域名端口三者之间任意一个与当前页面 url 不同即为跨域。

解除浏览器的跨域限制

//chrome 浏览器
--args --disable-web-security  --user-data-dir=关闭安全策略后的用户信息路径
//safari 浏览器 
open -a '/Applications/Safari.app' --args --disable-web-security --user-data-dir 

Mac 用户 : 打开终端输入 open -n /Applications/Google\Chrome.app/ --args --disable-web-security  --user-data-dir=路径
Win 用户 : 新建快捷方式 在目标那一栏后面添加 --args --disable-web-security  --user-data-dir=路径

SharedScreenshot.jpg

JSONP

什么是JSONP ?
引用W3C里的介绍:JSONP ( JSON with Padding ) 是 JSON 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
那么他的原理是什么呢 ? 这个也是在面试过程中经常遇到的问题。
利用 <script> 标签请求接口,因为 src 属性是没有跨域限制的,接口方只需提供一个回调函数来接受数据即可,<img><link> 这类标签也有 src 属性, 他们也一样可以绕过同源限制。
但 JSONP 只支持 GET 请求!

nginx 代理

nginx 是一个高性能的 HTTP 和反向代理 web 服务器,用 nginx 反向代理实现跨域,只需要修改 nginx 的配置即可。
进入 nginx 的安装目录,找到 nginx.conf 配置文件进行设置
假设:后端提供的接口为 www.a.com/xxx 我们想把 www.a.com 转发到本地并用 localhost/api 进行访问 , 前端项目区分一下 开发环境 和 测试环境 根据环境替换不同的接口即可。(前端项目 和 本地代理的端口需要一致)
大概配置如下:

server {
        listen       80;
        server_name  localhost;
        location ^~ /apis/ {
            proxy_pass http://www.a.com/;
        }
        location / {
            root   html;
            index  index.html index.htm;
        }
    }

CORS

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。并且支持现代浏览器,IE支持10以上。
CORS 支持所有类型的 HTTP 请求。而 JSONP 只支持 GET 请求, JSONP 的优势在于支持老式浏览器,以及可以向不支持 CORS 的网站请求数据。

如果后端同学方便操作,可以拜托后端同学在请求头加上 Origin 对应的设置。
跨域限制只存在浏览器,如果后端同学不方便加上的话,我们也可以用 Node 请求接口,然后在本地起一个端口,设置相应的请求头,前端项目判断环境请求本地接口也是可以的。

设置请求头的代码如下

// node
app.all('*', (req, res, next) => {  
    res.header("Access-Control-Allow-Origin", "*");  // 针对哪个域名可以访问,* 表示所有
    res.setHeader('Access-Control-Allow-Credentials', true);  // 是否可以携带cookie
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); 
    res.header("Content-Type", "application/json;charset=utf-8");  
    next();  
});  

如果想深入了解,推荐阅读阮一峰老师的这篇文章 www.ruanyifeng.com/blog/2016/0…

Webpack && Vite 的 Proxy 配置

proxy 设置只是一层代理,用于把指定的 path,代理后端提供的地址

webpack-dev-server 通过 http-proxy-middleware 插件实现 , vite 通过 http-proxy 插件实现
其原理都是用 Node 来做 Server 做中转代理。

// 基础用法
// 本地调用 - 假设前端项目启动端口为80 则应该访问 localhost/api/XXXX 
proxy: {
  '/api':{ // 这个是你要替换的位置
      target: '后端URL'//这个是被替换的目标地址
      changeOrigin: true // 默认是 false,如果需要代理需要改成 true
    }
}

如果想获取更多配置可查看以下文档:
webpack : webpack.docschina.org/configurati…
vite : cn.vitejs.dev/config/#ser…

最后说多几句

上面列举的几个方法都是日常开发中比较常用的方法。

还有一种方法是用 koa || express 配合 http-proxy-middlewarehttp-proxy 此类插件做一个中转服务。如果以上列举的几种方法满足不了开发场景,需要自定义开发的,或许这种方法会更适用。但如果不是的话,建议还是不要增加项目的复杂度。

跨域问题是面试官常问的题目,希望这篇文章能对大家有所帮助,祝大家能够找到满意的工作。