1、jsonp
2、CORS
3、http proxy
4、nginx反向代理
5、postMessage
6、document.domain + iframe
7、window.name + iframe
8、location.hash + iframe
9、webSocket
1、jsonp
script标签的src属性没有跨域问题,可以利用这一特点实现跨域资源共享。
// localhost:5500
<script>
function test1(data) {
console.log(data)
}
</script>
<script src="http://localhost:8001/list?callback=test1"></script>
//localhost:8001
//使用了express搭建web服务器
const express = require('express'),
app=express()
app.listen(8001,()=>{
console.log('OK!')
})
app.get('/list',(req,res)=>{
let {callback}=req.query
let data={
code:0,
message:'this is send'
}
res.send(`${callback}(${JSON.stringify(data)})`)
})
缺点是只能使用get请求
2、CORS
需要后端实现。get、post等等都可以
后端用的express.js
//后端 http://127.0.0.1:8001
const express = require('express'),
app=express()
app.listen(8001,()=>{
console.log('OK!')
})
app.use((req,res,next)=>{
res.header('Access-Control-Allow-Origin','http://127.0.0.1:5500')
res.header('Access-Control-Allow-Credentials',true)
res.header('Access-Control-Allow-Headers','Content-Type,Content-Length,Authorization,Accept,')
res.header('Access-Control-Allow-Methods','PUT,POST,GET,DELETE,OPTIONS,HEAD')
next()
})
app.get('/list',(req,res)=>{
let data={
code:0,
message:'this is send'
}
res.send(data)
})
//前端 http://127.0.0.1:5500
//使用axios发送请求
<script src="axios.js"></script> //引入axios
<script>
axios.get('http://127.0.0.1:8001/list').then(res=>{
console.log(res)
})
</script>
3、http proxy
使用webpack的webpack-dev-server实现
在webpack.config.js配置文件中加入以下代码:
devServer:{
proxy: {
//所有以/api开头的请求都会被代理到http://localhost:3000
"/api": "http://localhost:3000"
}
}
具体见webpack配置文档
4、nginx反向代理
在nginx的配置文件nginx.conf中做如下配置
server {
listen 80;
server_name www.test.com; //要访问的域名,我这里用的测试域名,如果有多个,用逗号分开
charset utf8;
location / {
proxy_pass http://proxy_test; //这里proxy_test是上面的负载的名称,映射到代理服务器,可以是ip加端口, 或url
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
5、postMessage
//localhost:5500 a.html
<body>
<iframe src="http://localhost:5501/b.html" id="testa" frameborder="0"></iframe>
<script>
testa.onload=function(){ //id为testa的iframe加载完毕
//向http://127.0.0.1:5501/b.html 发送消息
testa.contentWindow.postMessage('this is test send','http://127.0.0.1:5501/b.html')
}
window.onmessage=function(ev){ //监听其它页面发送过来的消息
console.log(ev.data) //输出发送来的消息
}
</script>
</body>
//localhost:5501 b.html
<script>
let name='this is b.html'
window.onmessage=function(ev){ //监听其它页面发送来的消息
console.log(ev.data) //输出其它页面发送来的消息
//向http://127.0.0.1:5500/a.html发送消息
ev.source.postMessage(name,'http://127.0.0.1:5500/a.html')
}
</script>
6、document.domain + iframe
只能实现同一个主域不同子域之间的操作
如 a.test.com和b.test.com就是同一个主域不同子域
//父页面 A a.test.com
<iframe src="http://b.test.com"></iframe>
<script>
document.domain = 'test.com'
var user = 'admin'
//子页面B b.test.com
<script>
document.domain='test.com'
alert(window.parent.user)
</script>
7、window.name + iframe
// http://127.0.0.1:5500 a.html
<iframe src="http://127.0.0.1:5501/b.html" id="testa" frameborder="0"></iframe>
<script>
let count=0
testa.onload=function(){
//判断count等于0 是为了防止onload事件反复触发
if(count===0){
//需要我们先把地址重新定向到同源中才可以
testa.src='http://127.0.0.1:5500/proxy.html'
count++
return;
}
//如果不把testa的src指定到一个同源的页面中而直接输出
//5501 b页面传过来的值的话,会出现跨域问题而无法输出
//将testa的src指定到一个空白的同源页面,不会覆盖掉5501 b页面传过来的值
console.log(testa.contentWindow.name)
}
</script>
// http:127.0.0.1:5501 b.html
window.name='this is b.htmlllll'
// http:127.0.0.1:5500 proxy.html
//proxy.html为空
8、location.hash + iframe
// a c页面同源 b非同源
// http://127.0.0.1:5500 a.html
<iframe src="http://127.0.0.1:5501/b.html" id="testa" frameborder="0"></iframe>
<script>
let count=0
testa.onload = function () {
if(count===0){
//向b.html传hash值
testa.src = 'http://127.0.0.1:5501/b.html#msg=yaochuandezhi'
count++
return;
}
}
//开放给同域c.html的回调方法
function func(res) {
console.log(res)
}
</script>
// http://127.0.0.1:5501 b.html
<iframe src="http://127.0.0.1:5500/c.html" id="iframe" frameborder="0"></iframe>
<script>
let iframe= document.querySelector('#iframe')
//监听a传来的hash值,再传给c.html
window.onhashchange=function(){
console.log(location.hash)
iframe.src="http://127.0.0.1:5500/c.html"+location.hash
}
</script>
// http://127.0.0.1:5500 c.html
<script>
//监听b传来的hash值
window.onhashchange=function(){
//在通过操作同域a的js回调,将结果传回
window.parent.parent.func(location.hash)
}
</script>
9、webSocket
//客户端
<script src="./socket.io.js"> </script>
<script>
let socket = io('http://127.0.0.1:5501')
//连接成功
socket.on('connect', function () {
//监听服务端消息
socket.on('message', function (msg) {
console.log('data from server:' + msg)
})
//监听服务端关闭
socket.on('disconnect', function () {
console.log('server socket has closed')
})
})
//发送消息给服务端
socket.send('lalalalallala')
</script>
//服务端 用node和express搭建
//安装socket模块 监听socket连接:server是服务器创建的服务
socket.listen(server).on('connection',function(client){
//接收消息
client.on('message',function(msg){
client.send(msg+'fasdlfasdfasf')
})
//断开处理
client.on('disconnect',function(){
console.log('client socket has closed')
})
})