跨域
跨域名访问,如c1.com域名向c2.com域名发送请求
本质:浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。
django服务端准备
url.py:
from django.conf.urls import url from hello import views urlpatterns = [ url(r'cors/', views.cors, name='cors'), url(r'jsonp/', views.jsonp, name='jsonp'), ]
views.py:
#!/usr/bin/env python # -*- coding: utf-8 -*- from django.http import HttpResponse from django.shortcuts import render from django.views.decorators.csrf import csrf_exempt @csrf_exempt def cors(request): n1 = request.POST.get('n1') n2 = request.POST.get('n2') result = int(n1) + int(n2) response = HttpResponse(result) response['Access-Control-Allow-Origin'] = "*" return response @csrf_exempt def jsonp(request): func_name = request.GET.get('callback') n1 = request.GET.get('n1') n2 = request.GET.get('n2') result = int(n1) + int(n2) temp = "%s(%s)" % (func_name, result) response = HttpResponse(temp) return response
实现Ajax跨域请求
a.跨域资源共享(CORS,Cross-Origin Resource Sharing)
执行流程:
服务端
- 设置响应头
客户端
- XmlHttpRequest 直接发送请求
cors.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>跨域请求</title> </head> <body> <h1>跨域请求</h1> <input type="submit" value="XmlSendRequest" onclick="XmlSendRequest();"/> <input type="submit" value="JqSendRequest_1" onclick="JqSendRequest_1();"/> <input type="submit" value="JqSendRequest_2" onclick="JqSendRequest_2();"/> <script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script> // 客户端定义回调函数 function call(arg) { console.log('客户端定义回调函数执行:', arg); } function XmlSendRequest() { // 创建script标签 var tag = document.createElement('script'); // 指定src tag.src = "http://localhost:8000/jsonp/?callback=call&n1=2&n2=4"; // 添加到head标签中 document.head.appendChild(tag); // 删除script标签 document.head.removeChild(tag); } function JqSendRequest_1() { $.ajax({ url: "http://localhost:8000/jsonp/", data: {'n1': 22, 'n2': 44}, type: 'POST', // 虽然是POST方式,但是内部会转换成GET请求 dataType: 'jsonp', success: function (data, statusText, xmlHttpRequest) { console.log('success 回调执行:', data); } }) } function JqSendRequest_2() { $.ajax({ url: "http://localhost:8000/jsonp/", data: {'n1': 222, 'n2': 444}, type: 'GET', // POST 也会自动转换为GET请求 dataType: 'jsonp', jsonp: "callback", jsonpCallback: 'call', // 请求成功返回后,客户端执行call函数 success: function (data, statusText, xmlHttpRequest) { // 未指定jsonCallback时,则自定执行方法 console.log('success 回调执行:', data); } // 如上请求如 http://localhost:8000/jsonp/?callback=call&n1=222&n2=444 }) } </script> </body> </html>
测试结果如:
b.JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”)
本质:利用script标签的src属性(浏览器允许script标签跨域)
(img src, iframe, script 都可以进行跨域)
执行流程:(注意:所有都是GET请求)
服务端:
- 直接返回 回调函数名
客户端:
- 客户端定义回调函数
- 直接发送请求
jsonp.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>跨域请求</title> </head> <body> <h1>跨域请求</h1> <input type="submit" value="XmlSendRequest" onclick="XmlSendRequest();"/> <input type="submit" value="JqSendRequest_1" onclick="JqSendRequest_1();"/> <input type="submit" value="JqSendRequest_2" onclick="JqSendRequest_2();"/> <script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script> // 客户端定义回调函数 function call(arg) { console.log('客户端定义回调函数执行:', arg); } function XmlSendRequest() { // 创建script标签 var tag = document.createElement('script'); // 指定src tag.src = "http://localhost:8000/jsonp/?callback=call&n1=2&n2=4"; // 添加到head标签中 document.head.appendChild(tag); // 删除script标签 document.head.removeChild(tag); } function JqSendRequest_1() { $.ajax({ url: "http://localhost:8000/jsonp/", data: {'n1': 22, 'n2': 44}, type: 'POST', // 虽然是POST方式,但是内部会转换成GET请求 dataType: 'jsonp', success: function (data, statusText, xmlHttpRequest) { console.log('success 回调执行:', data); } }) } function JqSendRequest_2() { $.ajax({ url: "http://localhost:8000/jsonp/", data: {'n1': 222, 'n2': 444}, type: 'GET', // POST 也会自动转换为GET请求 dataType: 'jsonp', jsonp: "callback", jsonpCallback: 'call', // 请求成功返回后,客户端执行call函数 success: function (data, statusText, xmlHttpRequest) { // 未指定jsonCallback时,则自定执行方法 console.log('success 回调执行:', data); } // 如上请求如 http://localhost:8000/jsonp/?callback=call&n1=222&n2=444 }) } </script> </body> </html>
测试结果:
***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***