Jsonp跨域请求

来源:互联网 发布:nginx 与 keepalive 编辑:程序博客网 时间:2024/06/14 13:51

浏览器的同源策略

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
三者有一个不同则会产生跨域。

跨域的几种解决方案

1,通过后台通过代理获取其它域名下的数据

2,CORS

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing),它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

Access-Control-Allow-Origin 该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求

3,JSONP

JSONP和JSON不一样,它并不是一种数据格式。而一种JavaScript实现跨域数据访问的方式。

JSONP跨域的原理

在浏览器中,script、img、iframe、link等标签都可以加载跨域资源,而不受同源限制。
而Jsonp就是利用script标签可以加载外部标签这一特性来实现跨域请求。下面看一个小demo。

数据库如图:
这里写图片描述

php代码

<?php    class Lists {        public $id;        public $name;        public $url;        public $country;    }    function connect() {        $localhost = 'localhost';        $username = 'root';        $password = 'root';        $database = '10086q';        $con = mysqli_connect($localhost,$username,$password,$database);        if (mysqli_connect_error($con)) {            echo "连接错误".mysqli_connect_error();            return null;        }        return $con;    }    $conn = connect();    $sql = 'select * from websites';    $res = mysqli_query($conn,$sql);    $data = array();    if ($res->num_rows > 0) {        while ($row = $res->fetch_assoc()) {            $list = new Lists();            $list->id = $row['name'];            $list->name = $row['name'];            $list->url = $row['url'];            $list->country = $row['country'];                    array_push($data,$list);        }    } else {        echo "没有数据";    }    //判断是否为跨域    if (isset($_REQUEST['callback'])) {        $callback = $_REQUEST['callback'];        $str = json_encode($data);        echo $callback.'('.$str.')';    } else {        echo json_encode($data);    }?>

前端代码

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>    </head>    <body>    </body>    <script type="text/javascript">        var xhr = new XMLHttpRequest();        xhr.open('get','http://127.0.0.1:83/test/0513/cross_domain/jsonp.php',true);        xhr.send();        xhr.onreadystatechange = function () {            if (xhr.readyState == 4 && xhr.status == 200) {                var data = xhr.responseText;                console.log(data);                console.log(typeof data);                 data = JSON.parse(data);                console.log(data);                console.log(typeof data);            }        }    </script></html>

上面是用http协议请求的代码,浏览器显示如图:
这里写图片描述

前端代码2

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>    </head>    <body>    </body>    <script type="text/javascript">        function ojson(data) {            console.log(data);        }    </script>    <script src="http://127.0.0.1:83/test/0513/cross_domain/jsonp.php?callback=ojson" type="text/javascript" charset="utf-8"></script></html>

这次用的是file协议,浏览器显示如图:
这里写图片描述
请求同一个api接口,file协议也能够获取到数据,只是要预定义一个全局的回调函数,并将函数名作为参数传给服务端。而服务端的代码则需要通过判断是否有回调来执行对应的操作。服务端返回的是一个回调函数的执行。

//isset可以用来判断是否为跨域if (isset($_REQUEST['callback'])) {    $callback = $_REQUEST['callback'];    $str = json_encode($data);    //输出用获取的回调函数操作的数据    echo $callback.'('.$str.')';} else {    echo json_encode($data);}
原创粉丝点击