浅谈跨域

216 阅读1分钟

跨域(非同源策略请求)

  • 同 源策略请求 ajax / fetch
  • 跨域传输

部署到web服务器上:同源策略

  • xampp 修改本地的host文件
127.0.0.1:1234  http://api.qq.com/

http://172.0.0.1:1234/index.html

api.qq.com/getData

服务器拆分 web服务器: 静态资源 kbs.sports.qq.com data服务器:业务逻辑和数据分析 api.spotys.qq.com 图片服务器:

三者都一样就是同源,只要有一个不同就是跨域

  • 协议
  • 域名
  • 端口号

web服务器地址:http://127.0.0.1:3000/index.html 数据接口地址: http://127.0.0.1:4000/list

1.JSONP

  • script
  • img
  • link
  • iframe
  • ... => 不存在跨域请求的限制

问题: JSONP只能处理GET请求

2.CORS(跨域资源共享)

  • 客户端:发送ajax/fetch请求

//axios 配置

	axios.defaults.baseURL = "http://127.0.0.1:8888";
    axios.defaults.wodthCredentials = true;
    axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    axios.defaults.transformRequest = function (data) {
    	if(!data) return data;
        let result = ``;
        for(let attr in data) {
        	if(!data.hadOwnProperty(attr)) break;
            result += `&${attr}=${data[attr]}`;
        }
        return result.substring(1);
    };
    axios,interceptors.reaponse.use(function onFulfilled(response){
    	return response.data;
    }, function onRejected(reason) {
    	return Promise.reject(reason);
    });
    axios.defaults.valifdateStatus = function(status) {
    	return /^(2|3)\d{2}$/.test(status);
    }
  • 服务端设计相关的头信息(需要处理options试探性请求)
	app.use((req,res,next) => {
    	res.header("Access-Control-Allow-Origin","http://localhost:8000");
        // =>* 【支持多源】(不能允许携带cookie)/ 具体地址
        res.header("Access-Control-Allow-Credentials", true);
        res.header("Access-Control-Allow-Headers", "Content-type-Content-Length,Authorization,Accept,X-Requested-With");
        res.header("Access-Control-Allow-Methods","PUT, POST, GET, DELETE, HEAD, OPTIONS");
        if(req.method === "OPTION"){
        	res.send("ok");
            return;
        }
        next();
    })

3.http proxy => webpack webpack-dev-server

配置 webpack.config.js 文件(node 中间件)

let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'production',  //生产模式(编译后能进行压缩)
    entry: './src/index.js', //入口
    output: {   //出口
        filename: 'bundle.min.js',
        path: path.resolve(__dirname, 'build')
    },
    //启动服务
    devServer: {
        port: 3000,
        progress: true,  //打包进度
        contentBase: './build', //指定访问静态资源目录
        // proxy代理 跨域
        proxy: {
            '/': {
                target: 'http://127.0.0.1:9090',
                changeOrigin: true
            }
        }
    },
    plugins: [   //阐述html插件的应用
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html'
        })
    ]
}

4.nginx 反向代理(不需要前端,都是服务器部署)

#proxy服务器

www.luci.cn -> www.luci.com

	server {
    	listen 80;
        server_name www.luci.com;
        location / {
        	proxy_pass www.luci.cn;  //反向代理
            proxy_cookie_demo www.luci.cn www.luci.com;
            add_header Access-Control-Allow-Origin www.luci.cn;
            add_header Access-Control-Allow-Credentials true;
        }
    }

5.postMessage

a.html -> b.html

a.html

<body>
    1111

    <iframe id="iframe" src="http://127.0.0.1:1002/MESSAGE/b.html" frameborder="0" style="display: none;"></iframe>

    <script>
        iframe.onload = function () {
            iframe.contentWindow.postMessage('lalalal','http://127.0.0.1:1002')
            
        }
        //监听b传递的信息
        window.onmessage = function(ev) {
            console.log(ev.data  + "++++++++++++");
            // =>ev.source:a
            // ev.source.postMessage(ev.data + '@@@' , ev.origin);
        }
    </script>
</body>

b.html

<body>
    2222
    <script>
        //监听a发送过来的信息
        window.onmessage = function(ev) {
            console.log(ev.data + '1111');

            // =>ev.source:a
            // console.log()
            ev.source.postMessage(ev.data + '@@@' , '*');
        }
    </script>
</body>