ajax操做基於瀏覽器的xmlHttpRequest對象,IE低版本是另一個對象,jQuery 1 版本對那兩個對象作了封裝,兼容性最好,2 、3版本再也不支持IE低版本了。javascript
Ajax操做,用來偷偷發請求。php
參考博客:html
http://www.cnblogs.com/wupeiqi/articles/5703697.htmlhtml5
void open(String method,String url,Boolen async)
用於建立請求
參數:
method: 請求方式(字符串類型),如:POST、GET、DELETE...
url: 要請求的地址(字符串類型)
async: 是否異步(布爾類型)
void send(String body)
用於發送請求
參數:
body: 要發送的數據(字符串類型)
void setRequestHeader(String header,String value)
用於設置請求頭
參數:
header: 請求頭的key(字符串類型)
vlaue: 請求頭的value(字符串類型)
String getAllResponseHeaders()
獲取全部響應頭
返回值:
響應頭數據(字符串類型)
String getResponseHeader(String header)
獲取響應頭中指定header的值
參數:
header: 響應頭的key(字符串類型)
返回值:
響應頭中指定的header對應的值
void abort()
終止請求
a. Number readyState 狀態值(整數) 詳細: 0-未初始化,還沒有調用open()方法; 1-啓動,調用了open()方法,未調用send()方法; 2-發送,已經調用了send()方法,未接收到響應; 3-接收,已經接收到部分響應數據; 4-完成,已經接收到所有響應數據; b. Function onreadystatechange 當readyState的值改變時自動觸發執行其對應的函數(回調函數) c. String responseText 服務器返回的數據(字符串類型) d. XmlDocument responseXML 服務器返回的數據(Xml對象) e. Number states 狀態碼(整數),如:200、404... f. String statesText 狀態文本(字符串),如:OK、NotFound...
ajax.htmljava
<body> <input type="text" /> <input type="button" value="Ajax1" onclick="Ajax1();" /> <script> function Ajax1(){ var xhr = new XMLHttpRequest(); // 建立XMLHttpRequest對象 xhr.open('GET','/ajax_json/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完畢 var obj = JSON.parse(xhr.responseText); console.log(obj) } }; xhr.setRequestHeader('k1','v1'); // 設置數據頭 xhr.send("name=root;pwd=123"); } </script> </body>
urls.pyjquery
url(r'^ajax_json/', views.ajax_json), url(r'^ajax/', views.ajax),
views.pyajax
def ajax(request): return render(request, "ajax.html") def ajax_json(request): print(request.POST) ret = {'code':True, 'data':None} import json # return HttpResponse(json.dumps(ret),status=404,reason='Not Found') # 定義狀態碼及狀態信息 return HttpResponse(json.dumps(ret))
上面發送的是GET請求,若是是POST請求呢?django
如上若是是POST請求,views裏 print(request.POST)
是沒有數據的,由於POST請求須要給加上請求頭。json
<script> function Ajax1(){ var xhr = new XMLHttpRequest(); // 建立XMLHttpRequest對象 xhr.open('POST','/ajax_json/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完畢 var obj = JSON.parse(xhr.responseText); console.log(obj) } }; xhr.setRequestHeader('k1','v1'); // 設置數據頭 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); xhr.send("name=root;pwd=123"); } </script>
如下幾種寫法,都是同樣的效果瀏覽器
> XMLHttpRequest XMLHttpRequest() > window.XMLHttpRequest XMLHttpRequest() > window['XMLHttpRequest'] XMLHttpRequest()
<script type="text/javascript"> function getXHR(){ // 兼容性判斷 var xhr = null; if(XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); } return xhr; } function XhrPostRequest(){ var xhr = getXHR(); // 定義回調函數 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已經接收到所有響應數據,執行如下操做 var data = xhr.responseText; console.log(data); } }; // 指定鏈接方式和地址----文件方式 xhr.open('POST', "/test/", true); // 設置請求頭 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); // 發送請求 xhr.send('n1=1;n2=2;'); } function XhrGetRequest(){ var xhr = GetXHR(); // 定義回調函數 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已經接收到所有響應數據,執行如下操做 var data = xhr.responseText; console.log(data); } }; // 指定鏈接方式和地址----文件方式 xhr.open('get', "/test/", true); // 發送請求 xhr.send(); } </script>
若是在jquery的ajax的回調函數裏,再寫上一些參數,裏面的參數接收的就是xmlHttpRequest對象,功能和上面是如出一轍的。
iframe標籤,會把網址嵌套在網頁中,iframe裏的網址更改,網頁是不刷新的。
<iframe src="http://blog.csdn.net/lgeng00"></iframe>
示例:輸入 http://……
網址,跳轉
<body> <input type="text" id="url" /> <input type="button" value="Iframe請求" onclick="iframeRequest();" /> <iframe src="http://blog.csdn.net/lgeng00" id="ifm"></iframe> <script src="/static/jquery-1.12.4.js"></script> <script> function iframeRequest(){ var url = $('#url').val(); console.log(url); $('#ifm').attr('src',url); } </script> </body>
能夠把form提交轉交給iframe,iframe提交,利用這個特性,實現僞ajax操做。
ajax.html
<form action="/ajax_json/" method="POST" target="ifm1"> {% csrf_token %} <iframe id="ifm1" name="ifm1"></iframe> <input type="text" name="username" placeholder="用戶名"/> <input type="text" name="email" placeholder="郵箱地址"/> <input type="submit" value="Form提交"> </form>
views.py
def ajax_json(request): print(request.POST) ret = {'code':True, 'data':request.POST.get('username')} import json return HttpResponse(json.dumps(ret))
在一些新版本的瀏覽器裏,iframe標籤竟然自動跳轉,禁用以下:
在iframe標籤中增長兩個屬性:
security="restricted" sandbox=""
前者是IE的禁止js的功能,後者是HTML5的功能。恰好就可讓IE,Chrome,Firefox這三大瀏覽器都實現了禁止iframe的自動跳轉。
瀏覽器審查元素中,iframe加載的時候在document對象裏,至關於一個上下文或者空間管理,在HTML裏面又嵌套了一個HTML。不能經過之前的方法獲取到。
iframe接收到服務端返回的數據後,會執行onload
事件,獲取返回數據以下:
<form action="/ajax_json/" method="POST" target="ifm1"> {% csrf_token %} <iframe id="ifm1" name="ifm1" onload="iframeLoad();"></iframe> <input type="text" name="username" placeholder="用戶名"/> <input type="text" name="email" placeholder="郵箱地址"/> <input type="submit" value="Form提交" onclick="submitForm();"/> </form> <script src="/static/jquery-1.12.4.js"></script> <script> function submitForm(){ // 當點擊提交的時候,纔給iframe綁定load事件 // 比在html中這樣添加好一點:<iframe name="ifm1" onload="iframeLoad();"></iframe> $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); // document對象下面的值 var obj = JSON.parse(text); console.log(obj); }) } function iiframeLoad(){ console.log(123) } </script>
若是發送的是【普通數據】 : jQuery > XMLHttpRequest > iframe
urls.py
url(r'^upload/$', views.upload), url(r'^upload_file/', views.upload_file),
views.py
def upload(request): return render(request,'upload.html') def upload_file(request): username = request.POST.get('username') fafafa = request.FILES.get('fafafa') import os img_path = os.path.join('static/imgs/',fafafa.name) with open(img_path,'wb') as f: for item in fafafa.chunks(): f.write(item) ret = {'code': True , 'data': img_path} # 返回文件路徑(圖片預覽用) import json return HttpResponse(json.dumps(ret))
upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .upload{ display: inline-block;padding: 10px; background-color: #2459A2; color: white; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 90; } .file{ width: 60px;height: 30px;opacity: 0; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 100; } </style> </head> <body> <div style="position: relative;width: 60px;height: 30px;"> <input class="file" type="file" id="fafafa" name="afafaf" /> <a class="upload">上傳</a> </div> <input type="button" value="提交XHR" onclick="xhrSubmit();" /> <input type="button" value="提交jQuery" onclick="jqSubmit();" /> <hr/> <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1"> <iframe id="ifm1" name="ifm1" style="display: none;"></iframe> <input type="file" name="fafafa"/> <input type="submit" onclick="iframeSubmit();" value="iframe提交"/> <!--iframe方式提交--> <hr>選中後,就上傳、圖片預覽 <!--iframe方式提交,選中後,就上傳,並圖片預覽--> <input type="file" name="fafafa" onchange="changeUpalod();" /> <!--iframe方式提交,選擇後,就圖片預覽--> </form> <div id="preview"></div> <!-- 圖片預覽使用 --> <script src="/static/jquery-1.12.4.js"></script> <script> // 選中後,就上傳文件,並圖片預覽 function changeUpalod(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); $('#preview').empty(); var imgTag = document.createElement('img'); imgTag.src = "/" + obj.data; $('#preview').append(imgTag); }); $('#form1').submit(); } // 第二種方式:基於jQuery方式上傳文件 function jqSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementById('fafafa').files[0]; // files表明上傳的文件 var fd = new FormData(); // 至關於表單 fd.append('username','root'); fd.append('fafafa',file_obj); $.ajax({ url: '/upload_file/', type: 'POST', data: fd, // 上傳文件時,添加如下兩個參數是告訴jQuery,不要作特殊處理 processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success:function(arg,a1,a2){ console.log(arg); console.log(a1); console.log(a2); // 多寫幾個參數,這個參數包含xmlHttpRequest對象 } }) } // 第一種方式:基於xmlHttpRequest方式上傳文件 function xhrSubmit(){ // $('#fafafa')[0] var file_obj = document.getElementById('fafafa').files[0]; var fd = new FormData(); fd.append('username','root'); fd.append('fafafa',file_obj); var xhr = new XMLHttpRequest(); xhr.open('POST', '/upload_file/',true); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 接收完畢 var obj = JSON.parse(xhr.responseText); console.log(obj); } }; xhr.send(fd); } // 第三種方式:基於iframe方式上傳文件 function iframeSubmit(){ $('#ifm1').load(function(){ var text = $('#ifm1').contents().find('body').text(); var obj = JSON.parse(text); // 圖片預覽 $('#preview').empty(); // 清空以前的預覽圖片 var imgTag = document.createElement('img'); imgTag.src = "/" + obj.data; // 綁定預覽圖片路徑 $('#preview').append(imgTag); }) } </script> </body> </html>
xmlHttpRequest和jQuery上傳文件,都是基於FormData,可是FormData對於IE一些低版本瀏覽器是不支持的。
通常狀況下,上傳圖片、頭像都是用iframe來實現的。
若是發送的是【文件】 : iframe > jQuery(FormData) > XMLHttpRequest(FormData)
流程:
/login/
實現:
頁面生成返回和生成圖片:生成網頁html、生成圖片url分開,這樣更新驗證碼圖片是,網頁是不用刷新的。
views
from io import BytesIO from django.shortcuts import HttpResponse from utils.check_code import create_validate_code def check_code(request): """ 驗證碼 :param request: :return: """ # 直接打開圖片,返回 # data = open('static/imgs/avatar/20130809170025.png','rb').read() # return HttpResponse(data) # 經過模塊生成圖片並返回 # 1. 建立一張圖片 pip3 install Pillow # 2. 在圖片中寫入隨機字符串 # obj = object() # 3. 將圖片寫入到指定文件 # 4. 打開指定目錄文件,讀取內容 # 5. HttpResponse(data) stream = BytesIO() # 在內存裏開闢一塊空間,在內存裏直接讀寫,至關於打開一個文件 img, code = create_validate_code() img.save(stream,'PNG') # 把生成的圖片進行保存 request.session['CheckCode'] = code # 把驗證碼放入session中 return HttpResponse(stream.getvalue()) # 在內存中讀取並返回
create_validate_code
font_type="Monaco.ttf", # 依賴的字體
html
<img src="/check_code.html" onclick="changeCheckCode(this);"> <script> function changeCheckCode(ths){ ths.src = ths.src + '?'; // URL不變:瀏覽器不發請求;加上?號,get參數請求,向後臺發請求 } </script>
check_code.py(依賴:Pillow,字體文件)
pip3 install Pillow
經常使用的富文本編輯器:CKEditor,UEEditor,TinyEditor,KindEditor
├── asp asp示例 ├── asp.net asp.net示例 ├── attached 空文件夾,放置關聯文件attached ├── examples HTML示例 ├── jsp java示例 ├── kindeditor-all-min.js 所有JS(壓縮) ├── kindeditor-all.js 所有JS(未壓縮) ├── kindeditor-min.js 僅KindEditor JS(壓縮) ├── kindeditor.js 僅KindEditor JS(未壓縮) ├── lang 支持語言 ├── license.txt License ├── php PHP示例 ├── plugins KindEditor內部使用的插件 └── themes KindEditor主題
<textarea name="content" id="content"></textarea> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/plugins/kind-editor/kindeditor-all.js"></script> <script> $(function () { initKindEditor(); }); function initKindEditor() { var kind = KindEditor.create('#content', { width: '100%', // 文本框寬度(能夠百分比或像素) height: '300px', // 文本框高度(只能像素) minWidth: 200, // 最小寬度(數字) minHeight: 400 // 最小高度(數字) }); } </script>
http://kindeditor.net/docs/option.html
items¶ # 配置顯示多少個工具 noDisableItems¶ # designMode 爲false時,要保留的工具,置灰 filterMode¶ # true時根據 htmlTags 過濾HTML代碼,false時容許輸入任何代碼。 resizeType¶ # 2或1或0,2時能夠拖動改變寬度和高度,1時只能改變高度,0時不能拖動。 syncType¶ # 設置」「、」form」,值爲form時提交form時自動提交,空時不會自動提交。 uploadJson¶ # 指定上傳文件的服務器端程序。 autoHeightMode¶ # 內容多時,自動調整高度。
<textarea id="content"></textarea> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/kindeditor-4.1.10/kindeditor-all.js"></script> <script> KindEditor.create('#content', { uploadJson: '/upload_img/', fileManagerJson: '/file_manager/', // 文件管理路徑 allowImageRemote: true, // 是否容許遠程上傳 allowImageUpload: true, // 是否容許本地上傳 allowFileManager: true, // 圖片空間,文件預覽功能 extraFileUploadParams: { // CSRF限制,提交csrf csrfmiddlewaretoken: "{{ csrf_token }}" }, filePostName: 'fafafa' // 設置文件發送的name值,方便後臺獲取 }); }) </script>
def upload_img(request): request.GET.get('dir') print(request.FILES.get('fafafa')) # 獲取文件保存 import json dic = { 'error': 0, 'url': '/static/imgs/20130809170025.png', 'message': '錯誤了...' } return HttpResponse(json.dumps(dic)) import os, time, json def file_manager(request): """ 文件管理,照片空間 :param request: :return: """ dic = {} root_path = 'C:/Users/Administrator/PycharmProjects/day24/static/' static_root_path = '/static/' request_path = request.GET.get('path') if request_path: abs_current_dir_path = os.path.join(root_path, request_path) move_up_dir_path = os.path.dirname(request_path.rstrip('/')) dic['moveup_dir_path'] = move_up_dir_path + '/' if move_up_dir_path else move_up_dir_path else: abs_current_dir_path = root_path dic['moveup_dir_path'] = '' dic['current_dir_path'] = request_path dic['current_url'] = os.path.join(static_root_path, request_path) file_list = [] for item in os.listdir(abs_current_dir_path): abs_item_path = os.path.join(abs_current_dir_path, item) a, exts = os.path.splitext(item) is_dir = os.path.isdir(abs_item_path) if is_dir: temp = { 'is_dir': True, 'has_file': True, 'filesize': 0, 'dir_path': '', 'is_photo': False, 'filetype': '', 'filename': item, 'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path))) } else: temp = { 'is_dir': False, 'has_file': False, 'filesize': os.stat(abs_item_path).st_size, 'dir_path': '', 'is_photo': True if exts.lower() in ['.jpg', '.png', '.jpeg'] else False, 'filetype': exts.lower().strip('.'), 'filename': item, 'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path))) } file_list.append(temp) dic['file_list'] = file_list return HttpResponse(json.dumps(dic))
轉載請務必保留此出處:http://www.cnblogs.com/lgeng/articles/7382196.html
<!-- END -->
《版本說明》: 本文轉自 -- http://blog.csdn.net/fgf00/article/details/54917439