URL | 结果 | 缘由 |
---|---|---|
http://a.xyz.com/dir2/other.html |
成功 | |
http://a.xyz.com/dir/inner/another.html |
成功 | |
https://a.xyz.com/secure.html |
失败 | 不一样协议 ( https和http ) |
http://a.xyz.com:81/dir/etc.html |
失败 | 不一样端口 ( 81和80) |
http://a.opq.com/dir/other.html |
失败 | 不一样域名 ( xyz和opq) |
<!DOCTYPE HTML> <html> <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>xyz</title> </head> <body> <button id="b1">点我</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> function rion(res) { console.log(res); } function addScriptTag(src) { var scriptEle = document.createElement("script"); $(scriptEle).attr("src", src); $("body").append(scriptEle); $(scriptEle).remove(); } $("#b1").click(function () { addScriptTag("http://127.0.0.1:8002/abc/?callback=rion") }); </script> </body> </html>
def abc(request): res = {"code": 0, "data": ["SNIS-561", "SNIS-517", "SNIS-539"]} func = request.GET.get("callback") return HttpResponse("{}({})".format(func, json.dumps(res)))
<!DOCTYPE HTML> <html> <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>xyz</title> </head> <body> <button id="b1">点我</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> $("#b1").click(function () { $.getJSON("http://127.0.0.1:8002/abc/?callback=?", function (res) { console.log(res); }) }); //要注意的是在url的后面必需要有一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务, // callback后面的那个?是jQuery内部自动生成的一个回调函数名。 </script> </body> </html>
<!DOCTYPE HTML> <html> <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>xyz</title> </head> <body> <button id="b1">点我</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> $("#b1").click(function () { $.ajax({ url: "http://127.0.0.1:8002/abc/", dataType: "jsonp", jsonp: "callback", jsonpCallback: "rion2" //若是服务端规定了回调函数名,可使用$.ajax方法来实现: }) }); function rion2(res) { console.log(res); } //不过一般都会将回调函数写在success回调中: $("#b1").click(function () { $.ajax({ url: "http://127.0.0.1:8002/abc/", dataType: "jsonp", success: function (res) { console.log(res); } }) }) </script> </body> </html>
一个请求须要同时知足如下两大条件才属于简单请求。css
(1) 请求方法是如下三种方法之一: HEAD GET POST (2)HTTP的头信息不超出如下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
在跨域场景下,当浏览器发送简单请求时,浏览器会自动在请求头中添加代表请求来源的 Origin 字段。html
后端程序只须要在返回的响应头中加上 Access-Control-Allow-Origin 字段,而且把该字段的值设置为 跨域请求的来源地址或简单的设置为 * 就能够了。jquery
例如:能够在Django中间件中的process_response方法来给相应对象添加该字段。git
from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 给响应头加上 Access-Control-Allow-Origin 字段 并简单的设置为 * response['Access-Control-Allow-Origin'] = '*' return response
解决办法:能够在后端简单的给响应对象添加上 经常使用请求方法(PUT、DELETE)的支持就能够了。github
from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 给响应头加上 Access-Control-Allow-Origin 字段 并简单的设置为 * response['Access-Control-Allow-Origin'] = '*' if request.method == 'OPTIONS': # 容许发送 PUT 请求 response['Access-Control-Allow-Methods'] = 'PUT, DELETE' # 容许在请求头中携带 Content-type字段,从而支持发送json数据 response['Access-Control-Allow-Headers'] = 'Content-type' return response
上面中间件确实能解决目前的CORS跨域问题,可是不够严谨,已经有人造好轮子-- django-cors-headers 了。 更多详细配置详细请查看django-cors-headers项目ajax
1.安装 pip install django-cors-headers 2.注册APP INSTALLED_APPS = [ ... 'app01.apps.App01Config', 'corsheaders', # 将 corsheaders 这个APP注册 ] 3.添加中间件 必须放在最前面,由于要先解决跨域的问题。只有容许跨域请求,后续的中间件才会正常执行。 MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 添加中间件 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] 4.配置 #能够选择不限制跨域访问 CORS_ORIGIN_ALLOW_ALL = True # 或者能够选择设置容许访问的白名单 CORS_ORIGIN_ALLOW_ALL = False CORS_ORIGIN_WHITELIST = ( # '<YOUR_DOMAIN>[:PORT]', '127.0.0.1:8080' )