使用jsonp和CORS解决跨域问题

156 阅读2分钟

1.创建本地服务端

// 1.引入express
const express = require('express');

// 2.创建应用对象
const app=express();

// 3.创建路由规则
// request是对请求报文的封装
// response是对响应报文的封装
app.get('/home',(request,response)=>{
    // 响应一个页面
    response.sendFile(__dirname + '/index.html');
});

app.get('/data',(request,response)=>{
    response.send('用户数据');
})

// jsonp
app.all('/jsonp',(request,response)=>{
   const data = {
       name:'yangy'
   };
    // 将数据转化为字符串
    let str = JSON.stringify(data);
    // 返回结果
    response.send(`handle(${str})`);
})

// 用户名检测是否存在
app.all('/username',(request,response)=>{
    const data = {
        exist:1,
        msg:'用户名已经存在'
    };
    // 将数据转化为字符串
    let str = JSON.stringify(data);
    // 返回结果
    response.send(`handle(${str})`);
})

app.all('/jquery-jsonp',(request,response)=>{
    const data = {
        name:'jsonp',
        city:['美国','上海','伦敦'],
    }
    // 将数据转化成字符串
    let str = JSON.stringify(data);
    // 接收callback参数
    let cb = request.query.callback;
    // 返回结果
    response.end(`${cb} (${str})`);
})

app.all('/cors',(request,response)=>{
    // 设置响应头
    response.setHeader("Access-Control-Allow-Origin","*");
    response.send('Hello CORS');
})

app.listen(9000,()=>{
    console.log('9000端口服务器已经启动....');
})

2.同源策略

1.同源策略是浏览器的一种安全策略
2.同源: 协议、域名、端口号 必须完全相同。
3.违背同源策略就是跨域

3.JSONP

	1.是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发来,
	只支持 get 请求。
	2.在网页有一些标签天生具有跨域能力,比如:img link iframe script。
	JSONP 就是利用 script 标签的跨域能力来发送请求的
	3.JSONP 的使用
	①.动态的创建一个 script 标签
	var script = document.createElement("script");
	②.设置 script 的 src,设置回调函数
	script.src = "http://localhost:3000/testAJAX?callback=abc";
	function abc(data) {
	alert(data.name);
	};
	③将 script 添加到 body 中
	document.body.appendChild(script);

格式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #result{
            width: 200px;
            height: 200px;
            border:1px solid #689;
        }
    </style>
</head>
<body>

    <div id="result"></div>
    
  
    <script>
        // 处理数据
        function handle(data){
            // 获取result元素
            const result =  document.getElementById('result');
            result.innerHTML = data.name;
        }
    </script>

<script src="http://127.0.0.1:9000/jsonp">

</script>

</body>
</html>

案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>案例</title>
</head>
<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";
                console.log(data);
                // 修改p 标签的提示文本
                p.innerHTML = data.msg;
            }

            // 绑定事件
            input.onblur = function(){
                // 获取用户的输入值
                let username = this.value;
                // 向服务器发送请求,检测用户名是否存在
                // 1.创建script标签
                const script = document.createElement('script');
                // 2.设置标签 src属性
                script.src = 'http://127.0.0.1:9000/username';
                // 3.将script插入到文档中
                document.body.appendChild(script);

            }
        </script>
</body>
</html>

4.使用jQuery发送JSONP

请求url一定要加参数callback且callback的值为?
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script  crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <title>Document</title>
    <style>
        #result{
            width: 300px;
            height: 200px;
            border: solid 1px #089;
        }
    </style>
</head>
<body>
        <button>点击发送jsonp请求</button>
        <div id="result">

        </div>
        <script>
            $('button').eq(0).click(function(){
                $.getJSON('http://127.0.0.1:9000/jquery-jsonp?callback=?',function(data){
                    console.log(data);
                    $('#result').html(`
                    名称: ${data.name},
                    校区: ${data.city},
                    `)
                });
            })
        </script>
</body>
</html>

5.CORS

1.CORS 跨域资源共享,CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中处理,
2.支持get和post请求,跨域资源共享标准新增了 一组http首部字段,允许服务器声明那些源站,通过浏览器有权限访问哪些资源
3.CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #result{
            width: 200px;
            height: 200px;
            border: solid 1px #689;
        }
    </style>
</head>
<body>
     <button>发送请求</button>
     <div id="result"></div>
     <script>
         const btn = document.querySelector('button');

         btn.onclick = function(){
            //  1.创建对象
            const xhr = new XMLHttpRequest();
            // 2.初始化设置请求方式和url
            xhr.open('GET','http://127.0.0.1:9000/cors');
            // 3.发送
            xhr.send();
            // 4.绑定事件
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status>=200 && xhr.status<300){
                        // 输出响应体
                        console.log(xhr.response);
                    }
                }
            }

         }
     </script>
</body>
</html>
//通过 res 来设置响应头,来允许跨域请求
//response.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:3000");
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Headers","*");
response.setHeader("Access-Control-Allow-Method","*");
response.send("testAJAX 返回的响应");
})

6.jsonp和CORS的区别

1.CORSJSONP的使用目的相同,但是比JSONP更强大
2.JSONP只支持GET请求,CORS支持所有类型的HTTP请求。
3.JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。