跨域以及解决办法

同源:符合“协议+域名+端口”三者相同,就是同源。

同源策略:同源策略,初衷是为了浏览器的安全性,保证浏览器不易受到XSS、CSFR等攻击。

同源策略限制的内容有:

  • Cookie、LocalStorage和IndexedDB等存储性内容
  • DOM和JS对象
  • AJAX请求发送后,被浏览器拦截

但是有三个标签是允许跨域加载资源

  • <img src=xxx>
  • <link href=xxx>
  • <script src=xxx>

JSONP和AJAX对比:

JSONP和AJAX相同,都是客户端想服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)。

JSONP优缺点:

优点:简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。

缺点:仅支持get方法具有局限性,不安全可能会遭受XSS攻击。

解决方案:

  1. 通过jsonp跨域
  2. document.domain + iframe跨域
  3. location.hash + iframe
  4. window.name + iframe
  5. postMessage跨域
  6. 跨域资源共享(CORS)
  7. nginx反向代理跨域
  8. nodejs中间件代理跨域
  9. webSocket协议跨域

 

JSONP的原理:

其本质是利用了script标签具有可跨域的特性,在页面中插入一个script标签,创建一个callback回调函数,通过服务器配合执行callback回调函数,并传入一些参数,最后将这些数据返回到客户端。

客户端:

<script>

       function fuc(data){

         console.log(data.name);

        }

</script>

<script src="http://www.baidu.com/api.php?callback=fuc"></script>

服务器端:

<?php

    $cb = $_GET['callback'];

    $data = array(

                'name'=> 'zs',

                'age'=>18,

                'gender'=>true

            );

    echo $cb.'('.json_encode($data).')';

?>

 

JSONP封装:

function jsonp({ url, params, callback }) {

  return new Promise((resolve, reject) ={

    let script = document.createElement('script')

    window[callback] = function(data) {

      resolve(data)

      document.body.removeChild(script)

    }

    params = { ...params, callback } // wd=b&callback=show

    let arrs = []

    for (let key in params) {

      arrs.push(`${key}=${params[key]}`)

    }

    script.src = `${url}?${arrs.join('&')}`

    document.body.appendChild(script)

  })

}

jsonp({

  url: 'http://localhost:3000/say',

  params: { wd: 'Iloveyou' },

  callback: 'show'

}).then(data ={

  console.log(data)

})

猜你喜欢

转载自blog.csdn.net/lianwenxiu/article/details/87921968