浏览器的同源策略

浏览器安全的基石是"同源政策"(same-origin policy)

含义:

1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。

最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。

  • 协议相同
  • 域名相同
  • 端口相同

举例来说,http://www.example.com/dir/page.html这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。

http://www.example.com/dir2/other.html:同源

http://example.com/dir/other.html:不同源(域名不同)

http://v2.www.example.com/dir/other.html:不同源(域名不同)

http://www.example.com:81/dir/other.html:不同源(端口不同)

摘自:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

下面就是一个同源策略的例子,项目2访问项目1的资源

项目1(http://127.0.0.1:8000):

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^send_ajax/', views.send_ajax),
]

views.py

from django.shortcuts import render, HttpResponse

def index(request):
    return render(request, 'index.html')

def send_ajax(request):
    print("index1")
    return HttpResponse("this is index1")

index.html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>index</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
<body>

<div class="container-fluid">
    <h1> index1页面</h1>
    <button class="send_ajax">send_ajax</button>
</div>
<script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>
<script>
    $(".send_ajax").click(function () {
        $.ajax({
            url: "/send_ajax/",
            success: function (data) {
                alert(data)
            }
        })
    })
</script>
</body>
</html> 

同时开启项目2(http://127.0.0.1:8010)

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^send_ajax/', views.send_ajax),
]

urls.py

views.py

from django.shortcuts import render, HttpResponse

def index(request):
    return render(request, 'index.html')

def send_ajax(request):
    print("---------index2----------")
    return HttpResponse("this is index2")

index.html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>index</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
<body>

<div class="container-fluid">
<h1> index2页面</h1>
<button class="send_ajax">send_ajax</button>
</div>
<script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>
<script>
    $(".send_ajax").click(function () {
        $.ajax({
            url:"http://127.0.0.1:8010/send_ajax/",
            success: function (data) {
                alert(data)
            }
        })
    })
</script>
</body>
</html> 

此时各自点击都可以正常使用

将项目2的index.html里ajax 的url改一下,去访问项目1的资源

<script>
    $(".send_ajax").click(function () {
        $.ajax({
            url:"http://127.0.0.1:8000/send_ajax/",
            success: function (data) {
                alert(data)
            }
        })
    })
</script>

此时会被浏览器阻止,因为浏览器的同源策略,这样的请求叫做跨域请求。

谷歌浏览器提示

火狐浏览器提示

请求是发出去了,只是被浏览器阻止了

解决跨域请求的解决方法有两个:

解决跨域请求,script src引入

项目2 index.html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>index</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
<body>

<div class="container-fluid">
    <h1> index2页面</h1>
    <button class="send_ajax">send_ajax</button>
</div>
<script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>

<script>

    function lcg(arg) {
        alert(arg)
    }
</script>
<script src="http://127.0.0.1:8000/send_ajax/"></script>

</body>
</html> 

项目1 views.py

from django.shortcuts import render, HttpResponse

def send_ajax(request):
    print("index1")
    return HttpResponse("lcg('hello  LCG')")

项目2访问http://127.0.0.1:8010/index/:

优化index:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>index</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
<body>

<div class="container-fluid">
    <h1> index2页面</h1>
    <button class="send_ajax">send_ajax</button>
</div>
<script src="{% static 'js/jquery-3.2.1.min.js' %}"></script>

<script>

    function lcg(arg) {
        alert(arg)
    }
    $(".send_ajax").click(function () {
        var $script = $("<script>");
        $script.attr("src", "http://127.0.0.1:8000/send_ajax/")
        $("body").append($script);
        $("body script:last").remove()
    })
</script>

</body>
</html> 

效果是一样的。script生成使用后立即删除。

优化成函数:

<script>

    function lcg(arg) {
        alert(arg)
    }
    function kuayu_request(url) {
        var $script = $("<script>");
        $script.attr("src", url);
        $("body").append($script);
        $("body script:last").remove()
    }
    $(".send_ajax").click(function () {
        kuayu_request("http://127.0.0.1:8000/send_ajax/")
    });

</script>

  

修改项目1的views.py 项目2的index.html

views.py

def send_ajax(request):
    print("index1")
    a = "hello lcg"
    return HttpResponse("lcg('%s')" % a)

index.html

<script>

    function lcg(arg) {
        console.log(arg)
    }
    function kuayu_request(url) {
        var $script = $("<script>");
        $script.attr("src", url);
        $("body").append($script);
        $("body script:last").remove()
    }
    $(".send_ajax").click(function () {
        kuayu_request("http://127.0.0.1:8000/send_ajax/")
    });

</script>

看似没问题,但是我只需要改一下项目1里的views.py。

def send_ajax(request):
    print("index1")
    a = "{'name':'lcg','age':'18'}"
    return HttpResponse("lcg('%s')" %a)

怎么办,我们想到了json。

关于json,参考这里(http://www.cnblogs.com/0bug/p/7994374.html)

views.py

def send_ajax(request):
    print("index1")
    a = json.dumps({'name': 'lcg', 'age': '18'})
    return HttpResponse("lcg('%s')" % a)

index.html

<script>

    function lcg(arg) {
        console.log(JSON.parse(arg))
    }
    function kuayu_request(url) {
        var $script = $("<script>");
        $script.attr("src", url);
        $("body").append($script);
        $("body script:last").remove()
    }
    $(".send_ajax").click(function () {
        kuayu_request("http://127.0.0.1:8000/send_ajax/")
    });

</script>

效果

优化:

views.py

def send_ajax(request):
    func_name=request.GET.get("callback")
    print("index1")
    a = json.dumps({'name': 'lcg', 'age': '18'})
    return HttpResponse("%s('%s')" %(func_name,a))

index.html

<script>

    function lcg(arg) {
        console.log(JSON.parse(arg))
    }
    function kuayu_request(url) {
        var $script = $("<script>");
        $script.attr("src", url);
        $("body").append($script);
        $("body script:last").remove()
    }
    $(".send_ajax").click(function () {
        kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=lcg")
    });

</script>

基于jquery 跨域请求 jsonp

views.py

def send_ajax(request):
    func_name=request.GET.get("callback")
    print("index1")
    a = json.dumps({'name': 'lcg', 'age': '18'})
    return HttpResponse("%s('%s')" %(func_name,a))

index.html

<script>

$(".send_ajax").click(function () {
    $.ajax({
        url: "http://127.0.0.1:8000/send_ajax/",
        dataType: "jsonp",
        jsonp: "callback",
        success: function (data) {
            console.log(data)
        }
    })
})
</script>

应用,访问云南电视台接口

已知接口:http://www.jxntv.cn/data/jmd-jxtv2.html

代码:

<script>
    $(".send_ajax").click(function () {
        $.ajax({
            url: "http://www.jxntv.cn/data/jmd-jxtv2.html",
            dataType: "jsonp",
            jsonp: "callback",
            jsonpCallback: "list"
        });

    });
    function list(shuju) {
        console.log(shuju)

    }
</script>

浏览器同源策略,跨域请求jsonp的更多相关文章

  1. JavaScript JSON timer(计时器) AJAX HTTP请求 同源策略 跨域请求

    JSON 介绍 1. JSON: JavaScript Object Notation 是一种轻量级的数据交换格式. 它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是 ...

  2. JavaScript JSON AJAX 同源策略 跨域请求

    网页和Ajax和跨域的关系 1 Ajax使网页可以动态地.异步地的与服务器进行数据交互,可以让网页局部地与服务器进行数据交互 2 Ajax强调的是异步,但是会碰到跨域的问题. 3 而有很多技术可以解决 ...

  3. 爬取斗图网图片,使用xpath格式来匹配内容,对请求伪装成浏览器, Referer 防跨域请求

    6.21自我总结 一.爬取斗图网 1.摘要 使用xpath匹配规则查找对应信息文件 将请求伪装成浏览器 Referer 防跨域请求 2.爬取代码 #导入模块 import requests #爬取网址 ...

  4. 循序渐进Python3(十一) --6--  Ajax 实现跨域请求 jsonp 和 cors

    Ajax操作如何实现跨域请求?       Ajax (XMLHttpRequest)请求受到同源策略的限制.       Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外 ...

  5. AJAX 跨域请求 - JSONP获取JSON数据

    Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示 ...

  6. 【JS跨域请求】Ajax跨域请求JSONP

    前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白 ...

  7. 【转】AJAX 跨域请求 - JSONP获取JSON数据

    来源:http://justcoding.iteye.com/blog/1366102/ Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流 ...

  8. Ajax的跨域请求——JSONP的使用

    一.什么叫跨域 域当然是别的服务器 (说白点就是去别服务器上取东西) 只要协议.域名.端口有任何一个不同,都被当作是不同的域. 总而言之,同源策略规定,浏览器的ajax只能访问跟它的HTML页面同源( ...

  9. ajax跨域请求-jsonp

    1. 同源策略 ajax之所以需要“跨域”,罪魁祸首就是浏览器的同源策略.即,一个页面的ajax只能获取这个页面相同源或者相同域的数据. 如何叫“同源”或者“同域”呢?——协议.域名.端口号都必须相同 ...

随机推荐

  1. PHP:第四章——PHP数组查找,替换,过滤,判断相关函数

    <pre> <?php //查找,替换,过滤,判断相关函数 header("Content-Type:text/html;charset=utf-8"); /*知 ...

  2. mac_os_x更新yosemite以后github客户端更新提示ca认证错误解决办法

    最近手贱更新了mac os yosemite的系统版本,更新以后发现部分软件无法使用,例如php 扩展的redis模块,mou,eclipse等等,甚是郁闷啊.对于图形化的软件还好说去官网更新一下新版 ...

  3. L1-050 倒数第N个字符串

    给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增.例如当 L 为 3 时,序列为 { aaa, aab, aac, . ...

  4. MyEclipse移动开发教程:迁移HTML5移动项目到PhoneGap(二)

    MyEclipse开年钜惠 在线购买低至75折!立即开抢>> [MyEclipse最新版下载] 二.将文件从HTML5项目复制到PhoneGap项目中 1. 在HTML5 app项目的ww ...

  5. Windows XP系统服役13年今正式退休

    清明已过,服役13年的微软Windows XP系统也于今日正式“退休”.尽管这之后XP系统仍可以继续使用,但微软不再提供官方服务支持.对于中国数以亿计的XP用户来说,一方面是对已经使用了13年的操作系 ...

  6. 福大软工1816 · 第八次作业(课堂实战)- 项目UML设计(团队)

    团队 学号 姓名 本次作业博客链接 031602428 苏路明(组长) https://www.cnblogs.com/Sulumer/p/9822854.html 031602401 陈瀚霖 htt ...

  7. docker中进行IDA远程调试提示“TRACEME: Operation not permitted[1] Closing connection from 192.168.109.1...”的解决方法

    加入 --security-opt seccomp:unconfined选项,关闭docker远程命令执行保护 如: docker run --security-opt seccomp:unconfi ...

  8. 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165202

    2018-2019-2 <网络对抗技术>Exp0 Kali安装 Week1 20165202 一.下载 虚拟机环境 Kali所需要虚拟机软件为VMware,在之前其他课程中使用的即为VMw ...

  9. <constant name="struts.devMode" value="false" />

    在开发中,我们常常会遇到<constant name="struts.devMode" value="false" />,这是struts2的特性, ...

  10. NBUT 1217 Dinner 2010辽宁省赛

    Time limit  1000 ms Memory limit  32768 kB Little A is one member of ACM team. He had just won the g ...