浏览器同源策略和跨域

148 阅读1分钟

什么是同源 同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。三者必须全部相同,缺一不可。

如果不同源,限制以下行为

  1. CookieLocalStorage 和 IndexDB 无法读取
  2. DOM 和 Js对象无法获得
  3. AJAX 请求不能发送

有三个标签是允许跨域加载资源

  • <img src=XXX>
  • <link href=XXX>
  • <script src=XXX>

jsonp就是通过script标签不受策略影响,实现的跨域资源共享。但是仅限Get请求。


 <script>
    const script = document.createElement('script')
    script.src = 'http://www.itcbc.com:3006/api/getscript2'
    document.head.appendChild(script)

    // http://www.itcbc.com:3006/api/getscript2  会返回一个show回调函数
    function show(res) {
      console.log(res);   // {message: '你必须自己定义好叫做show的函数,否则就会出错'}
    }
  </script>

所以,只要不同源,那么就要跨域。

跨域资源共享(CORS):主流的跨域解决方案。

1、跨域定义 只要协议、域名、端口有任何一个不同,都被当作是不同的域,前端跨域是浏览器特有的一种安全策略

2、作用范围 跨域是浏览器特有的一种安全机制,后端服务等不存在跨域情况

3解决的方案

  • a、后端设置响应头的 Access-Control-Allow-Origin 属性
// 全局拦截所有请求,做相关的操作
app.all('*', (req, res, next) => {
  if (req.method === 'OPTIONS') {
    return false;
  }
  
  // 支持跨域
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  res.header('Access-Control-Allow-Methods', '*');
  res.header('Content-Type', 'application/json;charset=utf-8');

  next();
});
  • b、前端通过代理的方式请求接口,如 webpack 的 devServer
devServer: {
    before: function (app, server, compiler) {
      /* mock 接口 */
      app.get('/api/demo', (req, res) => {
        setTimeout(() => {
          res.send({
            data: 'something...'
          })
        }, 5000)
      })
    },
    proxy: {
      '/api': {
        /*
         * 将来自 http://localhost:8000/api
         * 的请求资源全部转发为 /api开头的请求
         */
        target: 'http://localhost:8000/api',
        changeOrigin: true,
        secure: false,
        pathRewrite: {
          '^/api': ''
        }
      },
      '/tools': {
        /*
         * 将来自 http://www.tanglihe.cn/tools 
         * 的请求资源全部转发为 /tools开头的请求
        */
        target: 'http://www.tanglihe.cn/tools',
        changeOrigin: true,
        secure: false,
        pathRewrite: {
          '^/tools': ''
        }
      }
    }
  }