Django框架学习笔记—cors跨域

什么是跨域

跨域(跨源)是指浏览器从一个源的网页去请求另一个源,源指的是域名、端口、协议

以下都属于跨域问题:

域名: 
    主域名不同: http://www.baidu.com/index.html –> http://www.sina.com/test.js 
    子域名不同: http://www.666.baidu.com/index.html –> http://www.555.baidu.com/test.js 
    域名和域名ip: http://www.baidu.com/index.html –> http://180.149.132.47/test.js 
端口: 
	http://www.baidu.com:8080/index.html –> http://www.baidu.com:8081/test.js 
协议: 
	http://www.baidu.com:8080/index.html –> https://www.baidu.com:8080/test.js 
为什么要考虑跨域问题

因为Ajax不能跨域, 一旦客户端和服务端的不在一台服务器, 则需要考虑跨域访问的问题

同源策略

同源策略是浏览器的一项最为基本同时也是必须遵守的安全策略

同源策略的存在,限制了“源”自A的脚本只能操作“同源”页面的DOM,“跨源”操作来源于B的页面将会被拒绝

所谓的“同源”,必须要求相应的URI的域名、端口、协议均是相同的

使用Ajax发送请求的方式

现有如下的视图函数:

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

def get_data(request):
    return JsonResponse({'name':'慕容雪痕'})

现在分别使用JavaScript和jQuery去获取数据

JavaScript
// index.html
<script>
    var xhr = new XMLHttpRequest()
    xhr.open('GET','http://127.0.0.1:8000/getdata',true)
    xhr.send()
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200){
            console.log(xhr.responseText)
        }
    }
</script>
$.ajax
// index.html
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
    $.ajax({
            type: 'GET',
            url: 'http://127.0.0.1:8000/getdata/',
            success: function (data) {
                console.log(data)
            },
            error(e) {
                console.log(e)
            }
    })
</script>
$.get
// index.html
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
     $.get('http://127.0.0.1:8000/getdata/', function (data) {
     	console.log(data)
     })
</script>
$.post
// index.html
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
    $.ajaxSetup({
        data:{csrfmiddlewaretoken:'{{ csrf_token }}'}
    })
    $.post('http://127.0.0.1:8000/getdata/', function (data) {
        console.log(data)
    })
</script>

使用上面几种方法会造成跨域问题,当使用http://127.0.0.1:8000/index/访问时,可以正常得到数据,使用http://localhost:8000/index/访问就得不到数据,报如下错误

Access to XMLHttpRequest at 'http://127.0.0.1:8000/getdata' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
解决跨域问题
让服务器支持跨域(推荐)

(1) 安装django-cors-headers

pip install django-cors-headers

(2) 配置settings.py文件

INSTALLED_APPS = [
	'corsheaders',
]

MIDDLEWARE = [
	'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware', 
]
    
# 跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
	
# 跨域允许的请求方式(可选)
CORS_ALLOW_METHODS = (
	'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)
	
# 跨域允许的头部参数(可选)
CORS_ALLOW_HEADERS = (
	'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
)

(3) 使用ajax请求就可以实现跨域

使用 JSONP

一种非Ajax技术,需要前后端同时支持,只能用于GET请求

浏览器只对XMLHttpRequest请求有同源请求限制,而对script标签src属性、link标签ref属性和img标签src属性没有这种限制,利用这个“漏洞”就可以很好的解决跨域请求。

JSONP就是利用了script标签无同源限制的特点来实现的,当向第三方站点请求时,我们可以将此请求放在script标签的src属性里,这就如同我们请求一个普通的JS脚本,可以自由的向不同的站点请求

// index.html
<script src="http://127.0.0.1:8000/getdata"></script>

访问index.html,结果如下,证明跨域调用成功

[10/Aug/2019 09:56:08] "GET /index/ HTTP/1.1" 200 206
[10/Aug/2019 09:56:08] "GET /getdata/ HTTP/1.1" 200 36

JSONP基本使用如下:

例:index.html代码如下

<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
    $.ajax({
        url: 'http://127.0.0.1:8000/getdata/',
        dataType: 'JSONP',	// 使用JSONP
        jsonp: 'callback', // 传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
        jsonpCallback: 'fn', // 自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
        // 相当于在url中添加参数callback=fn
    })
    function fn(data) {
        console.log('--fn--:',data)
        // --fn--: {name: "慕容雪痕"}
    }

例:views.py代码如下

def get_data(request):
    callback = request.GET.get('callback')
    print(callback) # fn
    data = {"name":"慕容雪痕"}
    return HttpResponse('%s(%s)'%(callback,data))

例:在百度搜索框中输入qixijie,在输入框下方会有许多提示词汇(参数wd=qixijie)

// index.html

<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
    url = 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=1437,21118,29523,29521,29098,29568,28832,29221&wd=qixijie&req=2&bs=%E4%B8%83%E5%A4%95%E8%8A%82&pbs=%E4%B8%83%E5%A4%95%E8%8A%82&csor=7&pwd=qixiji&cb=jQuery1102040275346927984423_1565401956369&_=1565401956483'
    $.ajax({
        url: url,
        dataType: 'JSONP',
        jsonp: 'cb',
        jsonpCallback: 'fn',
    })
    function fn(data) {
        console.log('--fn--:',data)
    }
</script>

访问index.html,结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值