浏览器解决跨域问题

 

 -------------内容转载公众号 前端印象

1. JSOP 跨域解决

使用<Srcipt></Srcipt> 标签

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://www.b.domain.com:8080/main?callback=handleCallback';
    document.head.appendChild(script);

    // 回调函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>


handleCallback({"error": 0, "status": “0"})

JSONP看起来很方便,但是实际上限制很大。

由于scriptimg这些带src属性的标签,在引入外部资源时,使用的都是GET请求。

所以JSONP也只能使用GET发送请求,这也是这种方式已经逐渐被淘汰的原因。

2.代理跨域

Webpack Server代理

webpack中可以通过配置proxy来快速获得接口代理的能力,同时前端请求的URL不需要带域名,代理服务器会自动自动将请求映射为同域请求。

可在前端webpack.config.js配置代理:

module.exports = {
  ...
  output: {...},
  devServer: {
    port: 3000,
    proxy: {
      "/api": {
        target: "http://localhost:3001"
      }
    }
  },
  plugins: []
};

Nginx反向代理

实现思路其实与webpack代理一致,无非是通过Nginx作为跳板机而已。

server {
  listen   3000;
  server_name   localhost;
  
  location /api {
     proxy_pass    http://localhost:3001;  #反向代理
  }  
}

 

Node中间件代理

原理都是类似的,只不过是将代理操作设置在了后端。若是node项目的话,可以直接利用http-proxy-middleware插件进行代理。本质上webpack也是用这个包做代理服务的,只不过现在把这个放在服务端。

var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();

app.use('/', proxy({
    // 代理跨域目标接口
    target: 'http://localhost:3001',
    changeOrigin: true,

    // 修改响应头信息,实现跨域并允许带cookie
    onProxyRes: function(proxyRes, req, res) {
        res.header('Access-Control-Allow-Origin', 'localhost');
        res.header('Access-Control-Allow-Credentials', 'true');
    },
}));

app.listen(3000);

3 CORS跨域

一般现代浏览器都支持CORS跨域,只有那种古老的浏览器,比如IE10以下的才不支持。

这意味着,实际上浏览器虽然会采取同源策略来限制跨域访问,但是同时又给服务端提供了一个选择,即通过CORS来可选的提供跨域能力。

app.all('*', function (req: express.Request, res: express.Response, next: express.NextFunction) {
  //设置允许跨域的域名,*代表允许任意域名跨域
  res.header("Access-Control-Allow-Origin", "*");
  //允许的header类型
  res.header("Access-Control-Allow-Headers", "*");
  //跨域允许的请求方式
  res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
  if (req.method.toLowerCase() === 'options')
    res.sendStatus(200)  //让options尝试请求快速结束
  else
    next()
})

 

posted @ 2022-01-04 17:35  紫夜殇  阅读(155)  评论(0)    收藏  举报