美文网首页
实现前端跨域的几种方式

实现前端跨域的几种方式

作者: wayne1125 | 来源:发表于2019-08-19 14:49 被阅读0次

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)
})
  • server.js
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跨域实现方式

  • index.html
<!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>
  • server1.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')
        // 允许携带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后,可公用一份依赖包

相关文章

  • #hello,JS:15 同源策略 & 跨域(JSONP)

    跨域有几种常见的方式?你有没有跨域使用的经验? 方式: 使用jsonp实现跨域?使用cors实现跨域?浏览器另类的...

  • 实现前端跨域的几种方式

    1、jsonp跨域实现方式 server.js 2、CORS跨域实现方式 index.html server1.j...

  • JSONP跨域

    JSONP原理及应用 之前的文章中简单介绍过前端可以实现的跨域方式,这次介绍一种更为常用的跨域方式,但这种跨域方式...

  • Javascript跨域整理

    在前端的JS请求中,跨域的问题经常存在,根据不同的实现原理,常见的跨域的方法如下: 一:前端的方式 1:在前端页面...

  • Ajax 请求和跨域

    跨域的几种方式: cors方式 cross-orign-resource-shareing(跨域)参考:http:...

  • 关于设置env等环境变量的思考

    1、如何处理跨域后台处理跨域前端处理跨域浏览器处理跨域 前端本地处理跨域:代理线上跨域的处理方式:Nginx反向代...

  • vue-cli proxyTable配置

    前端的跨域转发 后端不需要配置,前端就可以实现跨域 proxyTable 的通常配置 这样就可以实现基本的跨域转发...

  • AngularJS实现跨域请求

    跨域,前端开发中常常遇到的问题。AngularJS实现跨域方式类似于Ajax。使用CORS机制。 以下阐述一下An...

  • 基于nodejs的跨域代理

    对于前端开发的童鞋,如果涉及到和后端协同开发,有可能会碰到跨域的问题,对于解决跨域的问题,目前有几种解决方式,例如...

  • 跨域的几种实现方式

    JSONP JSONP 是JSON with padding(填充式JSON 或参数式JSON)的简写;JSONP...

网友评论

      本文标题:实现前端跨域的几种方式

      本文链接:https://www.haomeiwen.com/subject/pczhjctx.html