实现前端跨域的几种方式

2019-08-19  本文已影响0人  wayne1125

1、jsonp跨域实现方式

function jsonp({url,params,cb}){
    return new Promise((resolve,reject) => {
        window[cb] = function (data) {
            resolve(data)
            document.body.removeChild(script)
        }
        params = {...params,cb} // { wd:b,cb:show }
        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(data => {
    console.log(data)
})
jsonp({
  url: 'http://localhost:3000/say',
  params: {wd: 'I love you'},
  cb: 'showLove'
}).then(data => {
  console.log(data)
})
let express = require('express')
let app = express()


app.get('/say', function (req, res){
  let {wd,cb} = req.query
  console.log(req.query,'query')
  console.log(wd)
  res.send(`${cb}('I love you to')`)
})

app.use(express.static(__dirname))

app.listen(3000)

2、CORS跨域实现方式

<!DOCTYPE html>
<html>
<head>
    <title>cors</title>
</head>
<body>
    <script type="text/javascript">
        let xhr = new XMLHttpRequest;
        document.cookie = 'name=wayne'
        xhr.withCredentials = true
        xhr.open('PUT','http://localhost:4000/getData',true)
        xhr.setRequestHeader('name', 'waynename')
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
                    console.log(xhr.response)
                    console.log(xhr.getResponseHeader('name'))
                }
            }
        }
        xhr.send()
    </script>
</body>
</html>
let express = require('express')
let app = express()
app.use(express.static(__dirname))

app.listen(3000)
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')
        // 允许携带Cookie
        res.setHeader('Access-Control-Allow-Credentials', true)
        // 允许返回的头
        res.setHeader('Access-Control-Expose-Headers', 'name')
        // 预检的存活时间
        res.setHeader('Access-Control-Max-Age', 1000)

        if(req.method === 'OPTIONS'){
            res.end() // OPTIONS请求不做任何处理
        }
    }
    next()
})

app.put('/getData',function(req,res){
    console.log(req.headers)
    res.setHeader('name','wayne')
    res.end('I dont‘t like you PUT')
})

app.get('/getData',function(req,res){
    console.log(req.headers)
    res.end('I dont‘t like you')
})


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

3、possMessage跨域实现方式

// a.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
     <iframe src="http://localhost:4000/b.html" frameborder="0" id="frame" onload="load()"></iframe>

     <script type="text/javascript">
        function load(){
            let frame = document.getElementById('frame')
            frame.contentWindow.postMessage('I love you','http://localhost:4000')
            window.onmessage = function (e){
                console.log(e.data)
            }
        }
     </script>
</body>
</html>

// a.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))

app.listen(3000)
// b.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
     <script type="text/javascript">
        window.onmessage = function (e){
            console.log(e.data)
            e.source.postMessage('I don’t love you', e.origin)
        }
     </script>
</body>
</html>
// b.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))

app.listen(4000)

4、window.name跨域实现方式

// a.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
     <iframe src="http://localhost:4000/c.html" frameborder="0" id="frame" onload="load()"></iframe>
     <script type="text/javascript">
        // a和b是同域 http://localhost:3000
        // c是独立的 http://localhost:4000
        // a获取c的数据
        // a先引用c  c把值放到window.name,把a引用的地址改到b
        let first = true
        function load(){
            if(first){
                let frame = document.getElementById('frame')
                frame.src = 'http://localhost:3000/b.html'
                first = false
            } else{
                console.log(frame.contentWindow.name)
            }
            
        }
     </script>
</body>
</html>
// a.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.listen(3000)

// b.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
     <script type="text/javascript">
     
     </script>
</body>
</html>

// b.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))

app.listen(4000)

// c.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

     <script type="text/javascript">
        window.name = 'I dont love you'
     </script>
</body>
</html>

5、hash跨域实现方式

// a.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

     <iframe src="http://localhost:4000/c.html#Iloveyou"></iframe>

     <script type="text/javascript">
        // 路径后面的值可以用来通信
        // 目的a想访问c
        // a给c传一个hash值 c收到hash值后 c把hash值传递给b b将结果放到a的hash值中
        window.onhashchange = function(){
            console.log(location.hash)
        }
     </script>
</body>
</html>

// a.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.listen(3000)

// b.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
     <script type="text/javascript">
        window.parent.parent.location.hash = location.hash
     </script>
</body>
</html>

// b.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.listen(4000)

// c.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
     <script type="text/javascript">
        console.log(location.hash)
        let iframe = document.createElement('iframe')
        iframe.src = 'http://localhost:3000/b.html#Idontloveyou'
        document.body.appendChild(iframe)
     </script>
</body>
</html>

6、document.domain

// a.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    hello a
     <iframe src="http://b.zf1.cn:3000/b.html" frameborder="0" onload="load()" id="frame"></iframe>

     <script type="text/javascript">
        // 域名,此用法限制是一级域名和二级域名的关系
        // a是通过 http://a.zf1.cn:3000/a.html
        document.domain = 'zf1.cn'
        function load() {
            console.log(frame.contentWindow.a)
        }
     </script>
</body>
</html>

// a.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.listen(3000)

// b.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    hello b
     <script type="text/javascript">
        document.domain = 'zf1.cn'
        var a = 100
     </script>
</body>
</html>

// b.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
app.listen(4000)

7、websocket跨域实现方式

// socket.html
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    websocket
     <script type="text/javascript">
        // 高级api 不兼容,一般使用socket.io做兼容
        let socket = new WebSocket('ws://localhost:9000')
        socket.onopen = function () {
            socket.send('I love you')
        }
        socket.onmessage = function (e) {
            console.log(e,e.data)
        }
     </script>
</body>
</html>

// server.js
let express = require('express')
let app = express()
let WebSocket = require('ws')
let wss = new WebSocket.Server({port: 9000})
console.log(123456)
wss.on('connection', function(ws){
    console.log(123)
    ws.on('message', function(data){
        console.log(data)
        ws.send('I dont love you')
    })
})
app.use(express.static(__dirname))
app.listen(3000)

8、nginx跨域实现方式

nginx反向代理方式之前总结过https://www.jianshu.com/p/96bc88beba91

image.png

文件夹crossDomain下执行 cnpm install express ws --save后,可公用一份依赖包

上一篇 下一篇

猜你喜欢

热点阅读