跨域


同源策略

同源策略最早由NETscape公司提出,是浏览器一种安全策略。

同源:协议、域名、端口号 必须完全相同

违背同源策略就是跨域

const btn = document.querySelector("button");
        btn.onclick = function(){
            const x = new XMLHttpRequest();
            //这里因为是满足同源策略的,所以url可以简写          
            x.open("GET","/data");
            //发送
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    if(x.status >=200 && x.status < 300){
                        console.log(x.response);
                    }
                }
            }
        }

服务器后端

const express = require('express');
const app = express();
app.get('/home',(request,response)=>{
    //响应一个页面
    response.sendFile(__dirname + "/index.html");
});
app.get('/data',(request,response)=>{
    response.send("用户数据");
});
app.listen(9000,()=>{
    console.log("服务已经启动……");
});

如何解决跨域

1.JSONP

JSONP是一个非官方的跨域解决方案,只支持get请求

通过script标签实现跨域

<script>
        function handle(data){
    //获取 result元素
    const result = document.getElementById("result");
    result.innerHTML = data.name;
}
    </script>
    <!-- <script src="./js/app.js"></script> -->
    <script src="http://127.0.0.1:8000/jsonp-server"></script>

后端js代码:

app.all('/jsonp-server',(request,response)=>{
    // response.send('console.log("helllo")'); //返回必须是js代码
    const data = {
        name:"山硅谷"
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //返回结果
    response.end(`handle(${str})`);
})

原生JSONP实践

4pzzn0.png

<body>
    用户名:<input type="text" id="username">
    <p></p>
    <script>
        //获取input元素
        const input = document.querySelector("input");
        const p = document.querySelector("p");
        //声明handle函数
        function handle(data){
            input.style.border = "solid 1px #f00";
            //修改p标签的提示文本
            p.innerHTML = data.msg;
        };
        //绑定实践
        input.onblur = function(){
            //获取用户输入值
            let username = this.value;
            //向服务器发送请求 检测用户名是否存在
            //创建script标签
            const script = document.createElement("script");
            //2.设置标签的src属性
            script.src = "http://127.0.0.1:8000/check-username";
            //3.将script插入到文档中
            document.body.appendChild(script);
        };
    </script>
</body>

后端JS

app.all('/check-username',(request,response)=>{
    // response.send('console.log("helllo")'); //返回必须是js代码
    const data = {
        exist: 1,
        msg: "用户名已经存在"
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //返回结果
    response.end(`handle(${str})`);
})

JQuery发送jsonp请求

<body>
    <button>点击发送jsonp请求</button>
    <div id="result">

    </div>
    <script>
        $("button").eq(0).click(function(){
            $.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?',function(data){
                $("result").html(`
                    名称: ${data.name}<br>
                    校区: ${data.city}
                `)
            });
        });
    </script>
</body>
app.all('/jquery-jsonp-server',(request,response)=>{
    // response.send('console.log("helllo")'); //返回必须是js代码
    const data = {
        name:"尚硅谷",
        city: ['北京','上海','深圳']
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //接收callback参数
    let cb = request.query.callback;

    //返回结果
    response.end(`${cb}(${str})`);
})

CORS

跨域资源共享,cors是官方的跨域解决方案,它的特点是不需要在客户端任何特殊的操作,完全在服务期进行处理,支持get和post请求。

const btn = document.querySelector("button");
        btn.onclick = function(){
            const x = new XMLHttpRequest();
            x.open("GET","http://127.0.0.1:8000/cors-server");
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    if(x.status >=200 && x.status < 300){
                        console.log(x.response);
                    }
                }
            }
        }
app.all('/cors-server',(request,response)=>{
    response.setHeader('Access-Control-Allow-Origin','*');
    // response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500');
    response.send("hello cors");
})

文章作者: Daniel Lin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Daniel Lin !
  目录