js和jquery使用jsonp解决跨域

    • 跨域
      • 使用 jsonp 来解决这个问题

跨域

理解跨域首先必须要了解同源策略。同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。

何谓同源:

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。

js和jquery使用jsonp解决跨域_第1张图片

由于同源策略,而且随着互联网的发展,“同源策略”越来越严格。目前,如果非同源,共有三种行为收到限制。

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 无法获得
  • Ajax 请求不能发送

同源政策规定,AJAX 请求只能发给同源的网址,否则就报错。
除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制。

  • JSONP
  • WebSocket
  • CORS

文本将介绍分别 js 和 jquery 来使用 jsonp。
后面所有的例子都是运行在服务器环境下的。


好的,用一个简单的例子来引入问题,先看下面的demo:


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Documenttitle>
  <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">script>
head>
<body>
  <script>
    $(document).ready(function(){
      document.write('加载baidu静态资源公共库');
    });
  script>
body>
html>

这是我们开篇用的那个例子,在服务器环境下,能够正常运行,页面会有显示,也就是说我们成功的加载了来自于百度静态资源公共库中的 jquery
对的,我们跨域了吗?我们跨域了吗?
在这个例子中,其实我们已经跨域了,因为

这个 jquery 来自于百度静态资源公开库,百度的这个域名肯定与我们本地的不同,但是我们却成功的加载了这段 jquery 代码到我们的页面上。这是为什么呢?

浏览器会进行同源检查(看清楚,这里是浏览器会进行同源检测。),这导致了跨域问题,然而这个跨域检查还有一个例外那就是 HTML 的 来加载跨域的资源的原因。


OK,下面我们来看一个 没跨域的情况下 使用 jquery 发出请求加载数据的例子:
后台代码(result.php):


    if($_GET) {
        $str = '{"id":"get"}'; 
        echo $str;
    }   
    if($_POST){
        $str = '{"id":"post"}'; 
        echo $str;
    }
?>

我们在 demo.html 中使用 jquery 分别使用 GET 和 POST 方式 向 result.php 发出请求:
demo.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
head>
<body>
    <a href="#" id="jq-get">jq-geta>
    <br>
    <a href="#" id="jq-post">jq-posta>
    <br>
    <p>后台返回的数据如下:p>
    <div id="result">div>
    <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">script>
    <script>
        $('#jq-get').click(function(){
            $.ajax({
                type: "GET",
                url: "http://10.2.229.89:8082/test-jq-jsonp/jsonp.php",
                data: {
                    "a": 1
                },
                dataType: "json",
                success: function(data){
                    $('#result').html(data.id);
                }
            });
        });

        $('#jq-post').click(function(){
            $.ajax({
                type: "POST",
                url: "http://10.2.229.89:8082/test-jq-jsonp/jsonp.php",
                data: {
                    "a": 1
                },
                dataType: "json",
                success: function(data){
                    $('#result').html(data.id);
                }
            });
        }); 
    script>
body>
html>

demo.html 与 result.php 均在 8082 端口下,不存在跨域的情况,
运行效果图如下:
js和jquery使用jsonp解决跨域_第2张图片

可见,在没有跨域的情况下,是很好用的。

下面,我们将 demo.html 移到本机的另一个端口(port: 3000)下,那么 demo.html 与 result.php 就存在了跨域的情况:
js和jquery使用jsonp解决跨域_第3张图片

使用 jsonp 来解决这个问题

$('#jq-get').click(function(){
    $.ajax({
        type: "GET",
        url: "http://10.2.229.89:8082/test-jq-jsonp/jsonp.php",
        data: {
            "a": 1
        },
        dataType: "jsonp",
        success: function(data){
            $('#result').html(data.id);
        }
    });
});

result.php也有一点改动

if($_GET) {
    $jsonp = $_REQUEST["callback"]; 
    $str = '{"id":"get"}'; 
    $str = $jsonp . "(" .$str.")"; 
    echo $str;
}

关于 jsonp 为什么要这么写,结合文章开头说的

你可能感兴趣的:(前端)