跨域

作者: 尼古拉特斯拉_9556 | 来源:发表于2018-10-13 21:39 被阅读0次

    跨域指的是访问不同源的url资源。
    浏览器出于对安全方面的考虑,只允许与本域中的接口进行交互。不同源的的客户端在没有明确授权的情况下,不能读写对方的资源。
    本域指的是
    1.同协议 例如都是 http 或者 https
    2.同域名 例如都是 baidu.com
    3.同端口 例如都是 8080 端口

    同源的例子
    https://www.baidu.com/ahttps://www.baidu.com/b

    不同源的例子
    http://www.baidu.comhttps://www.baidu.com 协议不同
    http://www.baidu.comhttp://taobao.com 域名不同
    http://www.baidu.com:8081http://www.baidu.com:8080 端口不同

    需要注意的是: 对于当前页面来说页面存放的 JS 文件的域不重要,重要的是加载该 JS 页面所在什么域。浏览器允许引用不同域的js,但是js发起ajax请求时,浏览器会判断当前域,与请求域是否一致,如果不一致,会拒绝接收请求域返回的数据。

    如何跨域?

    1.JSONP

    1.1 首先在浏览器脚本中定义一个callBack函数

    1.2 创建一个script脚本,并将script的src写为需要访问的接口地址,
    同时带上请求回调时的方法名称,这样服务端在返回数据时,将数据拼接在方法名
    中,浏览器读到脚本后,执行该函数,函数里可获得数据进行处理.

    
    代码
    
    客户端
    var script = document.createElement('script')
    script.src = 'http://localhost:8000?callBack=callBack'
    document.head.appendChild(script)
    function callBack(data){
          console.log(data.username)
          console.log(data.password)
    }
    
    服务端
    var http = require('http')
    var url = require('url')
    http.createServer(function(req,res){
        var pathObj = url.parse(req.url,true)
        var query = pathObj.query
        var callBack = query.callBack
        var data = {username:'jack',password:'123456'}
        res.end(callBack + '(' + JSON.stringify(data) + ')')
    }).listen(8000)
    
    

    总结,jsonp跨域原理是通过<script>标签引用接口,并且在本地定义好一个处理数据的函数,将函数名称传递后服务端,服务端接收到请求后,将数据放在拼装好的函数名称中,从而达到<script>标签请求完成后,执行函数,做到跨域数据处理。

    2.CORS

    客户端
    var xhr = new XMLHttpRequest();
    xhr.open('GET','http://localhost:8000',true)
    xhr.onload = function(){
        if(xhr.status == 200){
            data = JSON.parse(xhr.responseText)
            console.log(data.username)
            console.log(data.password)
        }
    }
    xhr.send()
    
    服务端
    var http = require('http')
    http.createServer(function (req,res) {
        res.setHeader('Access-Control-Allow-Origin','*')
        var data = {username:'jack',password:'123456'}
        res.end(JSON.stringify(data))
    }).listen(8000)
    

    当客户端发送一个跨域请求时,浏览器会自动在request header上加上
    Origin:http://localhost:80801(当前源)给服务端端

    服务端如果允许跨域请求的话,可以通过在 response header上加上
    Access-Control-Allow-Origin:源地址或者* (*代表的是所有的源都可以请求)
    来允许某些或者所有的源获取数据,当返回给客户端后,浏览器会拿服务端返回的
    Access-Control-Allow-Origin和客户端的Origin进行对比,如果匹配上了的话,客户端可以正常使用返回的数据,否则无法使用返回的数据。

    3.降域

    降域指的是,两个不同源的页面通过document.domain指定一级域名,并且他们的一级域名相同,然后来达到相互访问对方页面元素的跨域操作。(一级域名的意思请百度)

    http://a.local.com:8000/a.html
    
    <div>
        <h1>I am a Page</h1>
    </div>
    <div>
        <iframe src="http://b.local.com:8000/b.html"></iframe>
    </div>
    <script>
        document.domain = 'local.com'
        console.log(window.frames[0].document.head)
    </script>
    
    
    http://b.local.com:8000/b.html
    
    <h1>I'm b Page</h1>
    <script>
        document.domain = 'local.com'
    </script>
    

    4.postMessage

    采用 window.postMessage(this.value,'') 向目标窗口(window)发送一个message类型的消息,第一个参数是数据,第二个参数是源名称(代表所有源都可以接收,或者固定为固定的源,例如http://localhost:8080),
    目标窗口通过addEventListener('message')的方式得到数据,实现跨域操作。

    a.html
    <div>
        <h1>I am a Page</h1>
        <input>
    </div>
    <div>
        <iframe src="http://b.local.com:8000/b.html"></iframe>
    </div>
    <script>
        document.querySelector('input').addEventListener('input',function () {
            window.frames[0].postMessage(this.value,'*')
        })
    </script>
    
    b.html
    <h1>I'm b Page</h1>
    <input>
    <script>
    addEventListener('message',function (e) {
        console.log(e.data)
        document.querySelector('input').value = e.data
    })
    </script>
    

    相关文章

      网友评论

          本文标题:跨域

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