浏览器跨域安全和PHP处理

浏览器同源策略

如果两个URL的域名和端口都相同,则表示它们同源。在非同源的情况下,从一个域上加载的脚本(js),是不允许访问另外一个非同源域中的文档的。

跨域资源共享

跨域资源共享,是浏览器的一种机制,允许应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。header中定义的CORS,定义浏览器与服务器进行交互,以确定是否允许跨域请求的方法。

//表示对所示域名提供跨域权限,多个域名用','隔开,*表示允许所有,
Access-Control-Allow-Origin:www.why.com  

//允许请求的类型  
Access-Control-Request-Method:GET, POST

//指明实际请求中允许携带的首部字段
Access-Control-Allow-Headers:Content-Type, Authorization, Accept, Range, Origin

//在跨域访问时只能拿到Cache-Control,Content-Language,Content-Type,Expires、Last-Modified等基本相应头,如果要访问其他头,需要额外设置
Access-Control-Expose-Headers:Content-Range

//浏览器必须首先使用OPTIONS方法发起一个预检请求,从而获知服务端是否允许该跨域请求,这里指定了预检请求的结果能够被缓存多久
Access-Control-Max-Age:3600

JSONP资源加载安全

JSONP (json with padding)就是利用script标签的跨域能力实现跨域数据的访问,请求动态生成的js脚本同时带一个callback函数名作为参数。其中callback函数可以调用本地文档的js函数,服务器端动态生成的脚本会产生数据,并在代码中以产生的数据为参数调用callback参数。

是不是听起来有点晕?没关系,记住下面两点就好:

  • script脚本可以跨域请求
  • 请求的数据通过参数传回script脚本,写入页面
     

下面看个例子:

<meta content="text/html; charset=utf-8" http-equiv="Content-Type">

<script type="text/javascript">
    function jsonpCallback( result ) {
        var divs = document.getElementById('data');
        for( var i in result ) {
            divs.innerHTML += i + ":" + result[i] + "<br>";
        }
    }

    var JSONP = document.createElement("script");
    JSONP.type = "text/javascript";
    JSONP.src = "http://localhost:8080?callback=jsonpCallback";
    document.getElementsByTagName("head")[0].appendChild(JSONP);
/script>

<div id="data">    </div>
<?php

class Jsonp
{
    private $allowOrigin = [
        'http://localhost',
        'http://localhost:80',
        'http://localhost:8080',
    ];

    public function jsonpEncode($url, $callBack, $data )
    {
        if ( empty($_GET[$callBack]) ){
            return false;
        }

        if ( !$this->check($url) ){
            return false;
        }

        return $_GET[$callBack] . '(' . json_encode($data) . ')';
    }

    /**
     * @param $origin $_SERVER['HTTP_ORIGIN']
     */
    private function check($origin)
    {
        if ( !in_array($origin. $this->allowOrigin) ){
            return false;
        }
        $this->setAccess($origin);
    }

    private function setAccess($origin)
    {
        header('Access-Control-Allow-Origin:' . $origin);
        header('Access-Control-Allow-Credentials:true');
        header('Access-Control-Request-Method:GET, POST');
        header('Access-Control-Allow-Headers:Content-Type, Authorization, Accept, Range, Origin');
        header('Access-Control-Expose-Headers:Content-Range');
        header('Access-Control-Max-Age:3600');
    }
}
发布了253 篇原创文章 · 获赞 47 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/why444216978/article/details/104734226
今日推荐