跨域,jsonp,postMessage,cors,async和await

1.同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
现在所有的浏览器都支持同源策略
在前端工作中,会经常遇到跨域问题(同源策略问题),所谓同源,就是同协议,同域名,同端口

协议:http  https
域名:每一个网站都有自己的服务器,每一个服务器都有一个ip地址,每一个ip地址都会指向一个域名,域名有一级域名,二级域名和三级域名
http://aa(三级域名).aa(二级域名).com(一级域名)越往后范围越大

js中的同源,也就是协议,域名和端口都一致的时候,可以相互使用资源接口,因为他们是同源,否则就会有跨域问题

1.协议不同
http://www.baidu.com
https://www.baidu.com

2.域名不同
http://www.baidu.com
http://www.sian.com

3.端口不同
http://www.baidu.com:8080
http://www.baidu.com:5500

只有js才会考虑同源问题(<script>)
img  video  audio  等标签加载的时候不用考虑同源问题
但是浏览器设置了一些权限,标签也不能随意跨域

2.js怎么实现跨域

1.jsonp
2.在服务器端,设置 CORS 跨域资源共享
3.document.domain
4.html5的新增方法,postMessage方法,向不同源的页面发送信息

1.jsonp

1.创建script标签
2.在创建的标签添加src=接口地址,该接口地址就是需要跨域的地址,需要注意的是必须在路径上添加一个成功后的回调函数,另外要保证当前页面中有这个函数
3.把script标签放到body中
4.删除该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>jsonp</title>
</head>
<body>
  
 <input type="text" value="" id="txt"><br> 
 <button id="btn">点击</button>
 <button id="btn2">点击cors</button>
 <hr>
 <p id="msg"></p>

</body>
<script src="./js/jquery.js"></script>
<script type="text/javascript">

let btn=document.querySelector('#btn');
let txt=document.querySelector('#txt');
let msg=document.querySelector('#msg');

btn.οnclick=function(){
    let val=txt.value;
    // 创建script标签
    let ele=document.createElement('script');
    // 添加src
    ele.src='http://127.0.0.1/php/23jsonp.php?val='+val+'&cb=aa';//添加数据 val 和 回调函数aa
    //把script放在body中
    document.body.appendChild(ele);
    //删除script
    document.body.removeChild(ele);

}

function aa(str) {
    msg.innerHTML=str;
}

$('#btn2').click(function() {

    
    $.ajax({
        type:'get',
        data:{val:$('#txt').val()},
        url:'http://127.0.0.1/php/24cors.php',
        success(data){
            console.log(data);
            msg.innerHTML=data;
        }

    })
})
</script>
</html>
//后端23jsonp.php
<?php

$val=$_GET['val'];
$str=$val.'醉里挑灯看剑';
$cb=$_GET['cb'];
echo $cb.'("'.$str.'")';



?>

2.CORS 设置跨域

在服务器接口页面设置==header(‘Access-Control-Allow-Origin:*’);==即可访问,安全性差

<?php
//CORS 设置跨域
header('Access-Control-Allow-Origin:*');
$val=$_GET['val'];
$str=$val.'醉里挑灯看剑';
echo $str;

3.postMessage

在A页面中访问B页面中的元素
如果是同源页面,则可以直接访问
如果是不非同源页面,显示是没有问题的,但是要在a页面中操作b页面,则需要解决跨域问题
方法:主要是A页面设置 win.contentWindow.postMessage(‘haha’, ‘http://127.0.0.1’);
B页面添加信息事件监听window.addEventListener(‘message’, () => { if (event.data == ‘haha’) {} })

//A页面内部访问修改B页面内容
<!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>posA</title>
    <style type="text/css">
        .bor {
            border: 1px #f00 solid;
            width: 500px;
            height: 500px;

        }
    </style>
</head>

<body>
    <h1>A页面</h1>
    <iframe src="http://127.0.0.1/php/25posB.html" frameborder="0" class="bor" id="win"></iframe>
    <button id="btn">点击</button>

</body>
<script type="text/javascript">
    let btn = document.querySelector('#btn');
    let win = document.querySelector('#win');

    btn.onclick = function () {
        // 往b页面的window中提交信息,第一个参数是提交的信息,第二个参数是b页面所在的域
        win.contentWindow.postMessage('haha', 'http://127.0.0.1');
    }

</script>

</html>
//b页面
<!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>posB</title>
</head>

<body>
    <h1>B页面</h1>
    <p id="aa">
        万万没想到,啦啦啦
    </p>

</body>
<script type="text/javascript">
    window.addEventListener('message', () => {
        //  event 表示事件对象
        /*
        event.data页面传过来的内容
        event.target 当前页面的window对象
        event.srcElement 消息源页面的window对象
    
    
        */
        // console.log(event.data);
        // console.log(event.target);
        // console.log(event.srcElement);
        if (event.data == 'haha') {
            let p = document.getElementById('aa');
            p.style.fontSize = '30px';
            p.style.color = '#04be02';
        }
    });


</script>

</html>

4.jq中的jsonp

参数
{
   url 跨域访问的接口
   data 要提交的数据
   dataType 数据类型 jsonp
   jsonp 要传给后台的函数的键名
   jsonpCallback 要传给后台的函数名(也可以不写,直接是success函数)
   success 成功后的回调
}

ex:

$('#btn').click(function() {
    $.ajax({
        type:'get',
        data:{val:$('#txt').val()},
        dataType:'jsonp',
        jsonp:'cb',
        url:'http://127.0.0.1/php/23jsonp.php',
        // jsonpCallback:'aa',
        success(data){
            $('#msg').text(data);
            console.log('success:'+data);
        }
    })
})


function aa(data) {
    // $('#msg').text(data);
    console.log('aa:'+data);
}
<?php

$val=$_GET['val'];
$str=$val.'醉里挑灯看剑';
$cb=$_GET['cb'];
echo $cb.'("'.$str.'")';



?>

5.async和await

<!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>async和await</title>
</head>
<body>
    
</body>
<script src="./js/jquery.js"></script>
<script type="text/javascript">
/*
async 函数关键字,它修饰的函数,返回一个promise对象
ansyc 函数可以通过then方法获取函数的返回值 
一个单独的async的函数,实际上和一个promise实例是一样的
*/ 
async function aa() {
    return '天涯何处无芳草';

}
let p=aa();

console.log(p);
p.then(data=>{
    console.log(data);
})
/*
await(async wait:异步等待),它等待的是一个promise,所以await后面需要跟一个promise对象
await 必须放在async函数中才能使用

*/ 
function setData(type,url,data) {
    return new Promise((resolve,reject)=>{
        $.ajax({
         type:type,
         url:url,
         data:data,
         success(data){
             resolve(data);
         },
         error(err){
             reject(err);
         }
     });
    })
}
async function show() {
    console.log('开始');


    let a=await setData('post','promise.php',{name:'郭德纲'});
    console.log(a);
/*
如果await后面跟的不是一个promise对象,那么他会先转化成一个 立即执行resolve方法的promise,也就是把await后面的内容,当成一个成功的结果进行调用

*/ 
   let n=await 100;
   console.log(n);
   
   let m=await n+100;
   console.log(m);

    let b=await setData('post','promise.php',{name:'于谦'});
    console.log(b);
}
show();
/*
简单总结
async不会造成代码的阻塞,但是,await会造成async内部的代码阻塞
*/ 
// function run() {
//     console.log('春江花月夜');
//     let b=await setData('post','promise.php',{name:'于谦'});
//     console.log(b);
// }
// run();

/*
await 后面的promise对象,也有可能返回 reject,如果一个await返回的是reject,那么整个async函数都会被中断

可以使用 try..catch 语句来封装多个 await
*/ 
async function see() {
      try {//执行正确的代码
          console.log('开始');
          let a=await setData('post','promise.php',{name:'春伟 '});
          console.log(a);

          let err=await Promise.reject('错错错');
          console.log(err);

          let m=await 200;
          console.log(m);


      } catch (error) {
          //执行错误的操作
          console.log(error+'摸摸摸');
      }    
}
see();
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值