九种跨域方案解决(偏后台)

同源策略:协议、域名和端口号都一致叫同域

为什么浏览器不支持跨域呢?

  • cookie localstorage等等不支持跨域
  • dom元素也有同源策略,比如iframe
  • ajax不支持跨越

实现跨域:

  • jsonp
  • cors
  • postMessage
  • document.domain
  • window.name
  • location.hash
  • http-proxy
  • nginx
  • websocket

1 jsonp

<script type="text/javascript">
			//1jsonp
			// 缺点:只能发送get请求,不支持post put delete,不安全
			function jsonp({url,params,cb}){
				return new Promise((resolve,reject)=>{
					window[cb]=function(data){
						resolve(data);
						document.body.remove(script);
					}
					params={...params,cb}
					let arrs=[];
					for(let key in params){
						arrs.push(`${key}=${params[key]}`)
					}
					let script=document.createElement('script');
					script.src=`${url}?${arrs.join('&')}`;
					document.body.appendChild(script);
				})
			}
			jsonp({
				url:'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
				params:{
					wd:'b'
				},
				cb:'show'
			})
			.then(res=>{
				console.log(res)
			})
			.catch(err=>{
				console.log(err)
			})
		</script>

 

2 cors

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			//2cors
			let xhr=new XMLHttpRequest;
			document.cookie="name=afpx";
			// 强制带好凭证再发送请求
			xhr.withCredentials=true;
			xhr.open('PUT','http://localhost:4000/getData',true);
			xhr.setRequestHeader('name','afpx')
			xhr.onreadystatechange=function(){
				if(xhr.readyState==4){
					if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
						console.log(xhr.response)
					}
				}
			}
			xhr.send();
		</script>
	</body>
</html>

server.js

let express=require('express');
let app=express();

app.use(express.static(__dirname));
app.listen(3000);

server2.js

let express=require('express');
let app=express();
let whiteList=['http://localhost:3000']
app.use(function(req,res,next){
	let origin=req.headers.origin;
	if(whiteList.includes(origin)){
		// 设置哪个源可以访问
		res.setHeader('Access-Control-Allow-Origin',origin)
		// 设置加请求头
		res.setHeader('Access-Control-Allow-Headers','name')
		// 添加请求方法
		res.setHeader('Access-Control-Allow-Methods','PUT')
		// 预检的存活时间
		res.setHeader('Access-Control-Max-Age',6000)
               // 允许前端获取哪个头
		res.setHeader('Access-Control-Expose-Headers','name')
		if(req.method=='OPTIONS'){
			res.end();//OPTIONS请求不做任何处理
		}
	}
	next();
})
app.get('/getData',function(req,res){
	console.log(req.headers);
	res.end('hahaha')
})
app.put('/getData',function(req,res){
	console.log(req.headers);
	res.end('hahaha')
})
app.use(express.static(__dirname));
app.listen(4000);

 

3 postMessage

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<iframe 
		  src="http://localhost:4000/index2.html"
		  id="iframe"
		  onload="load()">
		</iframe>
		<script type="text/javascript">
			//3
			function load(){
				let frame=document.getElementById('iframe');
				frame.contentWindow.postMessage('我爱你','http://localhost:4000')
				window.onmessage=function(e){
					console.log(e.data)
				}
			}
		</script>
	</body>
</html>

index2.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			window.onmessage=function(e){
				console.log(e.data)
				e.source.postMessage('我不爱你',e.origin);
			}
		</script>
	</body>
</html>

server.js

let express=require('express');
let app=express();

app.use(express.static(__dirname));
app.listen(3000);

server2.js

let express=require('express');
let app=express();

app.use(express.static(__dirname));
app.listen(4000);

 

4 window.name

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<!-- index和index2是同域的,http://localhost:3000
		index3是独立的,http://localhost:4000
		index获取index3的数据	
		index先引用index3 index3把值放到window.name 把index引用的地址改到index2 -->
		<iframe 
		  src="http://localhost:4000/index3.html"
		  id="iframe"
		  onload="load()">
		</iframe>
		<script type="text/javascript">
			let first=true;
			function load(){
				if(first){
					let iframe=document.getElementById('iframe');
					iframe.src="http://localhost:3000/index2.html"
					first=false;
				}else{
					console.log(iframe.contentWindow.name)
				}
				
			}
		</script>
	</body>
</html>

index2.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			
		</script>
	</body>
</html>

index3.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			window.name="我不爱你"
		</script>
	</body>
</html>

server.js

let express=require('express');
let app=express();

app.use(express.static(__dirname));
app.listen(3000);

server2.js

let express=require('express');
let app=express();

app.use(express.static(__dirname));
app.listen(4000);

5 location.hash

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<!-- 路径后面的hash值可以用来通信 -->
		<!-- 目的:index想访问index3
		index给index3传一个hash值,
		index3收到hash值后
		index3把hash值传递给index2
		index2将结果放到index的hash值中 -->
		<iframe 
		  src="http://localhost:4000/index3.html#iloveyou"
		  id="iframe">
		</iframe>
		<script type="text/javascript">
			window.onhashchange=function(){
				console.log(location.hash)
			}
		</script>
	</body>
</html>

index2.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			window.parent.parent.location.hash=location.hash;
		</script>
	</body>
</html>

index3.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script>
			console.log(window.location.hash)
			let iframe=document.createElement('iframe');
			iframe.src="http://localhost:3000/index2.html#idontloveyou"
			document.body.appendChild(iframe);
		</script>
	</body>
</html>

6 document.domain

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		helloa
		<!-- 限制:必须是一级域名和二级域名的关系,并且配置 -->
		<!-- 一级域名 www.baidu.com -->
		<!-- 二级域名 viode.baidu.com -->
		<!-- index是通过http://localhost:3000/index.html -->
		<iframe 
		  src="http://localhost:3000/index2.html"
		  id="iframe"
		  onload="load()">
		</iframe>
		<script type="text/javascript">
			document.domain="zf1.cn"
			function load(){
				var iframe=document.getElementById('iframe')
				console.log(iframe.contentWindow.a);
			}
		</script>
	</body>
</html>

index2.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		hellob
		<script type="text/javascript">
			document.domain="zf1.cn"
			var a=100;
		</script>
	</body>
</html>

7 websocket

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			// 高级api 不兼容 socket.io(一般使用它)
			let socket=new WebSocket('ws://localhost:3000');
			socket.onopen=function(){
				socket.send('我爱你');
			}
			socket.onmessage=function(e){
				console.log(e)
			}
		</script>
	</body>
</html>

server.js

let express=require('express');
let app=express();
let WebSocket=require('ws');
let wss=new WebSocket.Server({port:3000});
wss.on('connection',function(ws){
	ws.on('message',function(data){
		console.log(data)
		ws.send('我不爱你')
	})
});

8 nginx

先下载nginx,然后配置

9 http-proxy

以后再学

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值