Django之APPEND_SLASH配置爬坑
入坑
测试妹纸∩︿∩反馈BUG,Django项目的某前端页面AJAX报错如下:
Mixed Content: The page at 'https://.../roles/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://.../role/1/'. This request has been blocked; the content must be served over HTTPS.
一顿某道翻译操作之后,大概意思是HTTPS的页面AJAX请求了一个HTTP协议的接口,由于某种安全机制,引发了 混合内容(Mixed Content)错误,所以该请求被阻止了。源码片段如下:
var role_id = $(this).attr('data-id');
$.ajax({
type: "GET",
url:"/role/"+role_id,
dataType: "json"
}).done(function(msg){
...
}).fail(function(msg){
...
});
爬坑
开发老司机告诉我们,从报错入手,先查了下什么是混合内容(Mixed Content)。
混合内容:初始 HTML 内容通过安全的 HTTPS 连接加载,但其他资源(例如,图像、视频、样式表、脚本)>则通过不安全的 HTTP 连接加载。因为页面通过 HTTPS 加载的初始请求是安全的,但是又加载了不安全的>HTTP内容,因此称之为混合内容。
因为HTTPS的S本身就是Secure的意思,现代浏览器最初会针对此类型的内容显示警告,以向用户表明此页面 包含不安全的资源。但是即使显示警告,页面也已经加载,用户的安全仍然受到了威胁。所以没过多久, Chrome和Firefox就直接阻断掉了这类的请求。这就是HTTPS页面为什么发送不了HTTP的原因。
what?也就是说,AJAX请求的URL是HTTP协议的?神奇,颠覆了我以往的认知,这种写法不应该是默认访问HTTPS协议的地址嘛?!漫漫爬坑路之开始。
- 第一次爬坑
直接把URL写成绝对的,代码修改如下:
var role_id = $(this).attr('data-id');
$.ajax({
type: "GET",
url:"https://..../role/"+role_id,
dataType: "json"
}).done(function(msg){
...
}).fail(function(msg){
...
});
第一次爬坑失败,分析:这种修改仍然无效的话,可能是Django的某种配置造成的。翻文档发现了APPEND_SLASH这个配置。官方文档介绍如下:
APPEND_SLASH¶
Default:
True
When set toTrue
, if the request URL does not match any of the patterns in the URLconf and it doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended. Note that the redirect may cause any data submitted in a POST request to be lost.
大概意思是,如果这个配置为True,请求到URL不能匹配到任何结果且不是以"/"结尾,则Django会自动增加"/"并以HTTP访问它。坑点就在这个HTTP上面呀,难怪不管怎么样都访问的HTTP!
- 第二次爬坑
将AJAX的URL后面加上"/",就能匹配到Django设置的URL了,成功解决问题。
填坑
BUG产生的主要原因是项目的URL配置不规范,为了阻止这种跳转,关闭了APPEND_SLASH,并且所有URL都改为以"/"结尾。URL是不是以"/"结尾的区别,可以看这篇文章:https://www.jianshu.com/p/83c2fa941fd8