面试官:什么是跨域,你如何处理跨域?

130 阅读2分钟

什么是跨域

跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。  但这个保护机制也带来了新的问题,它的问题是给不同站点之间的正常调用,也带来的阻碍,那怎么解决这个问题呢?接下来我们一起来看。

跨域三种情况

在请求时,如果出现了以下情况中的任意一种,那么它就是跨域请求:

  • 协议不同,如 http 和 https;
  • 域名不同;
  • 端口不同。

注意:跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了

如何处理跨域

解决跨域的方法有很多,下面列举了三种:

  • JSONP
  • CORS
  • Proxy

JSONP

JSONP是一种利用 <script> 标签不受同源策略限制的特性来实现跨域请求的方法。服务器返回的数据会被包裹在一个函数调用中,客户端定义该函数来处理数据。

<!-- 前端代码 -->
<script>
  function handleData(data) {
    // 处理返回的数据
  }
</script>
<script src="http://example.com/api/data?callback=handleData"></script>

CORS

CORS是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。CORS 实现起来非常方便,只需要增加一些 HTTP 头,让服务器能声明允许的访问来源。只要后端实现了 CORS,就实现了跨域。

koa框架举例添加中间件,直接设置Access-Control-Allow-Origin响应头。

app.use(async (ctx, next)=> {
  ctx.set('Access-Control-Allow-Origin', 'http://example.com'); // 允许的域
  ctx.set('Access-Control-Allow-Headers', 'Content-Type');// 允许的请求头
  ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');// 允许的方法
  if (ctx.method == 'OPTIONS') {
  // 如果是 OPTIONS 请求,直接返回状态码 200 表示接受预检请求
    ctx.body = 200; 
  } else {
  // 如果不是 OPTIONS 请求,执行下一个中间件
    await next();
  }
})

Proxy

通过在同源的服务器上设置代理,实现跨域请求。前端请求同源服务器,同源服务器再将请求发送到目标服务器,然后将目标服务器的响应返回给前端。

vue.config.js文件,新增以下代码

amodule.exports = {
    devServer: {
        host: '127.0.0.1',
        port: 8084,
        open: true,
        proxy: {
            '/api': { // '/api'是代理标识,用于告诉node,url前面是/api的就是使用代理的
                target: "http://xxx.xxx.xx.xx:8080", //一般是指后台服务器地址
                changeOrigin: true, //是否跨域
                pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'用""代替
                    '^/api': "" 
                }
            }
        }
    }
}

在对axios的再次封装中,配置请求的根路径。

axios.defaults.baseURL = '/api'