推薦一個讀者做的不錯的程式設計學習網站:
網站:潛安
域名:http://www.qianani.com
另外将會不定期推送近期網站用到的一些技術,講一些核心原理,今天為第一篇
問題由來:
最近一直在優化兩個Python學習網站,自己給自己提點需求,看看能不能實作,比如下方為http://www.python88.cn網站,在這個網站中,我做了一個功能,檢測使用者是否在該網站掃碼并輸入驗證碼,如果掃碼驗證過,則在後端記錄并傳回前端列印出來"right",如果沒有掃碼驗證,則傳回“error",傳回這樣标記的目的是為了通過這個标志是否做出右下角的彈窗,如果沒有驗證的使用者,則會彈出右下角的彈窗,當然在這個網站中這點已經很容易實作了
接下來需求就來了,下方是http://www.python66.cn第二個網站,因為我想通過http://python66.cn向http://python88.cn網站引流,點選彈窗能跳轉到http://88.cn網站,同樣,我也想通過使用者能否擷取在第一個網站掃碼(傳回的right或error)來判斷是否彈出下方的彈窗,這樣則牽涉到跨域請求
什麼是跨域請求:舉個例子:假如一個域名為http://aaa.cn的網站,它發起一個資源路徑為http://aaa.cn/book/100.html的 Ajax 請求,那麼這個請求是同域的,因為資源路徑的協定、域名以及端口号與目前域一緻(例子中協定名預設為http,端口号預設為80)。但是,如果發起一個資源路徑為http://bbb.com/doc的 Ajax 請求,那麼這個請求就是跨域請求,因為域不一緻,與此同時由于安全問題,這種請求會受到同源政策限制。
ajax隻能請求同一個域下的資料或資源,有時候需要跨域請求資料,就需要用到jsonp技術(還有其他方式也可以跨域請求),jsonp可以跨域請求資料,它的原理主要是利用了<script><img>标簽具有src屬性可以跨域連結資源的特性。jsonp和ajax原理完全不一樣,不過jquery将它們封裝成同一個函數。
如何了解<script><img>标簽具有src屬性标簽可以跨域連結資源?比如這是我在csdn的文章,裡面的圖檔引入的是我http://python88.cn的網站圖檔,就是典型的跨域,包括我們<script>标簽,有時候也會通過src引入一些網絡上的架構,也是這個道理,jsonp就是通過這樣的原理來實作的跨域
原理基于上面原理,但是一般我們在用的時候,通過jQuery封裝好的方法來進行使用,下面開始上代碼
1、首先我在後端視圖中定義一個book_ip_sign2函數,并同步配置url說明,jsonp跨域請求隻能接受get請求,不支援post請求
def book_ip_sign2(request):
user_ip = request.META['REMOTE_ADDR']
print("***********")
print(user_ip)
engine = get_local_engine()
ip_df = pd.read_sql("find_ip_num", engine)
ip_list = list(ip_df["ip"])
if user_ip not in ip_list:
print("新的使用者IP")
func = request.GET.get('callback', None)
context = {"user_ip": user_ip, "book_click_sign": "error","find_ip_num":num}
return HttpResponse("%s(%s)"%(func,context))
else:
current_user = FindIpNum.objects.filter(ip=user_ip)
current_num = current_user[0].num
if current_num < 3:
func = request.GET.get('callback', None)
context = {"user_ip": user_ip, "book_click_sign": "error","find_ip_num":current_num}
return HttpResponse("%s(%s)"%(func,context))
elif current_num >= 3:
func = request.GET.get('callback', None)
context = {"user_ip": user_ip, "book_click_sign": "right", "find_ip_num":current_num}
return HttpResponse("%s(%s)"%(func,context))
對于上面代碼,看着很多,不過你可以忽略那些業務邏輯,隻需要看傳回的資料即可,我這裡主要想傳回三個資料(book_click_sign , current_num, user_ip),直接将這幾個構造成context通過JsonResponse傳回是不行的,前端會報錯,後來找了點資料,發現要跟回調函數拼接,也就是下面的,func是回調函數名,通過拼接用HttpResponse進行傳回
func = request.GET.get('callback', None)
context = {"user_ip": user_ip, "book_click_sign": "right", "find_ip_num":current_num}
return HttpResponse("%s(%s)"%(func,context))
前端檢視該傳回結果是這樣的,括号中就是我們傳回前端的資料,也是回調函數的參數(回調函數名+參數)
jQuery17104493579000703556_1550910515349('error_0_139.227.3.199')
2、前端jsonp請求 前端引入jQuery,通過$.ajax進行請求,注意這裡的jsonp和ajax原理完全不一樣,這裡$.ajax .done .fail此類隻是jQuery官方将兩種請求封裝成了看起來類似的方法
核心請求頭就是url,type,dataType這些,如果請求成功,則通過.done寫js邏輯,如果請求失敗則通過.fail寫js邏輯
傳回的data: 後端回調函數括号中的參數即傳回前端的最終data
error_0_139.227.3.199
$.ajax({
url:'http://www.python88.cn/book_ip_sign2/',
type:'get',
dataType:'jsonp',
})
.done(function(data){
book_click_sign = data.book_click_sign;
find_ip_num = data.find_ip_num;
user_ip = data.user_ip;
console.log(user_ip)
console.log(find_ip_num)
console.log(book_click_sign)
if(book_click_sign=="error"){
$("#hzw_showmsg").delay(5000).slideDown(1000);
}else{
console.log("放過一次")
}
})
大家如果想測試,可以去http://www.python66.cn前端欄目下載下傳源碼,下載下傳後是一個html檔案,通過控制台就能看到跨域請求傳回的結果