AJAX全套
1.AJAX实现输入框两个数相加,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
""" Django settings for s4day79 project. Generated by 'django-admin startproject' using Django 1.11.1. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'o)rd6bws8#^4l*#l2*@e+u7so4oi766vqc7yapz5s4l*ylegf(' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True # ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', ] MIDDLEWARE = [ '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', ] ROOT_URLCONF = 's4day79.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 's4day79.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), )
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render,HttpResponse,redirect def index(request): return render(request,'index.html') def add1(request): a1 = int(request.POST.get('i1')) #POST取值 a2 = int(request.POST.get('i2')) #POST取值 return HttpResponse(a1 + a2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>首页</h1> <input type="text" id="i1" /> + <input type="text" id="i2" /> = <input type="text" id="i3" /> <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();"> <input type="button" id="btn2" value="原生Ajax" onclick="add2();"> {# <form action="/fake_ajax/" target="ifr">#} {# <iframe id="ifr" name="ifr"></iframe>#} {# <input type="text" name="user" />#} {# <a onclick="submitForm();">提交</a>#} {# </form>#} <script src="/static/jquery-3.2.1.js"></script> <script> function add1() { $.ajax({ url: '/add1/', type: 'POST', data: {'i1':$('#i1').val(),'i2':$('#i2').val()}, success:function (arg) { $('#i3').val(arg); } }) } function add2() { } </script> {# <script>#} {# function submitForm() {#} {# document.getElementById('ifr').onload = loadIframe;#} {# document.getElementById('f1').submit();#} {# }#} {# function loadIframe() {#} {# alert(123);#} {# }#} {# </script>#} </body> </html>
XMLHttpRequest使用:
GET请求
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render,HttpResponse,redirect def index(request): return render(request,'index.html') def add1(request): a1 = int(request.POST.get('i1')) a2 = int(request.POST.get('i2')) return HttpResponse(a1 + a2) def add2(request): if request.method == "GET": import time time.sleep(10) i1 = int(request.GET.get('i1')) i2 = int(request.GET.get('i2')) print('add2.....') return HttpResponse(i1+i2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>首页</h1> <input type="text" id="i1" /> + <input type="text" id="i2" /> = <input type="text" id="i3" /> <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();"> <input type="button" id="btn2" value="原生Ajax" onclick="add2();"> <script src="/static/jquery-3.2.1.js"></script> <script> function add1() { $.ajax({ url: '/add1/', type: 'POST', data: {'i1':$('#i1').val(),'i2':$('#i2').val()}, success:function (arg) { $('#i3').val(arg); } }) } function add2() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ {# 4-完成,已经接收到全部响应数据;#} alert('执行完成'); } }; xhr.open('GET','/add2/?i1=12&i2=20'); xhr.send(); } </script> </body> </html>
function add2() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ {# 4-完成,已经接收到全部响应数据;#} alert(xhr.responseText); 修改成xhr.responseText } }; xhr.open('GET','/add2/?i1=12&i2=20'); xhr.send(); }
弹框:
POST请求
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render,HttpResponse,redirect def index(request): return render(request,'index.html') def add1(request): a1 = int(request.POST.get('i1')) a2 = int(request.POST.get('i2')) return HttpResponse(a1 + a2) def add2(request): if request.method == "GET": # import time # time.sleep(10) i1 = int(request.GET.get('i1')) i2 = int(request.GET.get('i2')) print('add2.....') return HttpResponse(i1+i2) else: #POST请求 print(request.POST) return HttpResponse('ok')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>首页</h1> <input type="text" id="i1" /> + <input type="text" id="i2" /> = <input type="text" id="i3" /> <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();"> <input type="button" id="btn2" value="原生Ajax" onclick="add2();"> <script src="/static/jquery-3.2.1.js"></script> <script> function add1() { $.ajax({ url: '/add1/', type: 'POST', data: {'i1':$('#i1').val(),'i2':$('#i2').val()}, success:function (arg) { $('#i3').val(arg); } }) } function add2() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ {# 4-完成,已经接收到全部响应数据;#} alert(xhr.responseText); } }; xhr.open('POST','/add2/'); xhr.send('i1=12&i2=20'); } </script> </body> </html>
加POST请求,前端页面必须加请求头:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render,HttpResponse,redirect def index(request): return render(request,'index.html') def add1(request): a1 = int(request.POST.get('i1')) a2 = int(request.POST.get('i2')) return HttpResponse(a1 + a2) def add2(request): if request.method == "GET": # import time # time.sleep(10) i1 = int(request.GET.get('i1')) i2 = int(request.GET.get('i2')) print('add2.....') return HttpResponse(i1+i2) else: print(request.POST)#<QueryDict: {}> print(request.body)#请求体: b'i1=12&i2=20' return HttpResponse('ok')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>首页</h1> <input type="text" id="i1" /> + <input type="text" id="i2" /> = <input type="text" id="i3" /> <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();"> <input type="button" id="btn2" value="原生Ajax" onclick="add2();"> <script src="/static/jquery-3.2.1.js"></script> <script> function add1() { $.ajax({ url: '/add1/', type: 'POST', data: {'i1':$('#i1').val(),'i2':$('#i2').val()}, success:function (arg) { $('#i3').val(arg); } }) } function add2() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ {# 4-完成,已经接收到全部响应数据;#} alert(xhr.responseText); } }; xhr.open('POST','/add2/'); xhr.setRequestHeader('content_type','multipart/form-data'); #添加请求头 xhr.send('i1=12&i2=20'); } </script> </body> </html>
2. 伪Ajax,非XMLHttpRequest
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def autohome(request): return render(request,'autohome.html')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div> <input type="text" id="txt1" /> <input type="button" value="查看" onclick="changeSrc();" /> <input type="text"> <input type="text"> <input type="text"> <input type="text"> </div> <iframe id="ifr" style="width: 1000px;height: 2000px;" src="http://www.autohome.com.cn"></iframe> <script> function changeSrc() { var inp = document.getElementById('txt1').value; document.getElementById('ifr').src = inp; } </script> </body> </html>
用到的技术:
iframe标签,不刷新发送HTTP请求
<form>....</form> 把input框里的数据打包,页面刷新
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="text" /> <form method="POST" action="/fake_ajax/" target="ifr"> target="ifr" 这里相当于form不用原来一提交就刷新的方式了,而改为用iframe提交数据到后台 <iframe name="ifr"></iframe> <input type="text" name="user" /> <input type="submit" value="提交" /> </form> {#<form action="/fake_ajax/" target="ifr">#} {# <iframe id="ifr" name="ifr" style="display: none"></iframe>#} {#</form>#} </body> </html>
<form method="POST" action="/fake_ajax/" target="ifr">
target="ifr" 这里相当于form不用原来一提交就刷新的方式了,而改为用iframe提交数据到后台
用form+iframe伪造ajax,页面不刷新向后台发起请求
只要一提交返回数据,但是不刷新,成功伪造了ajax! (页面动了,这是chrome浏览器的特性,IE不会出现这个情况,但是没刷新,因为输入框的数据没有清空) ok是POST请求的返回值。
前端发数据,后台接收
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def fake_ajax(request): if request.method == "GET": return render(request,'fake_ajax.html') else: print('POST') print(request.POST)#<QueryDict: {'user': ['bingabcd']}>拿到提交的数据 return HttpResponse('ok')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{# <input type="text" />#} <form method="POST" action="/fake_ajax/" target="ifr"> <iframe name="ifr" style="display: none"></iframe> <input type="text" name="user" /> <input type="submit" value="提交" /> </form>
print(request.POST)#<QueryDict: {'user': ['bingabcd']}>拿到提交的数据
伪AJAX的"回调函数"
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> {# <input type="text" />#} <form method="POST" action="/fake_ajax/" target="ifr"> <iframe name="ifr" onload="loadIframe();"></iframe> <input type="text" name="user" /> <input type="submit" value="提交" /> </form> <script> function loadIframe() { alert(123); } </script> {#<form action="/fake_ajax/" target="ifr">#} {# <iframe id="ifr" name="ifr" style="display: none"></iframe>#} {#</form>#} </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def fake_ajax(request): if request.method == "GET": return render(request,'fake_ajax.html') else: print('POST') print(request.POST)#<QueryDict: {'user': ['bingabcd']}>拿到提交的数据 return HttpResponse('返回值')
错误信息 Uncaught ReferenceError: loadIframe is not defined 没有被定义,因为代码从上到下执行 at HTMLIFrameElement.onload (127.0.0.1/:10)
<iframe name="ifr" onload="loadIframe();"></iframe>第一次加载到内容,但是js代码在HTML代码下面还没执行,所以会报错。
<script>
function loadIframe() {
alert(123);
}
</script>
解决报错信息:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> {# <input type="text" />#} <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> <iframe id="ifr" name="ifr"></iframe> {# <iframe name="ifr" onload="loadIframe();"></iframe>#} <input type="text" name="user" /> {# <input type="submit" value="提交" />#} <a onclick="submitForm();">提交</a> </form> <script> function submitForm() { document.getElementById('f1').submit(); document.getElementById('ifr').onload = loadIframe; } function loadIframe() { alert(123); } </script> {#<form action="/fake_ajax/" target="ifr">#} {# <iframe id="ifr" name="ifr" style="display: none"></iframe>#} {#</form>#} </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> <iframe id="ifr" name="ifr"></iframe> <input type="text" name="user" /> <a onclick="submitForm();">提交</a> </form> <script> function submitForm() { document.getElementById('ifr').onload = loadIframe; document.getElementById('f1').submit(); 先给iframe标签 绑定回调函数,ifram负责给form提交数据,HTML代码从上到下执行,如果绑定的回调函数和绑定提交的函数没执行,上面的代码都不会执行,所以页面不会报错了 (先绑定再提交) } function loadIframe() { alert(123); } </script> </body> </html>
先给iframe标签 绑定回调函数,ifram负责给form提交数据,HTML代码从上到下执行,如果绑定的回调函数和绑定提交的函数没执行,上面的代码都不会执行,所以页面不会报错了
(先绑定再提交)
提交时 先弹出框,再出现返回值
基于Iframe和Form表单实现伪Ajax操作
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> <iframe id="ifr" name="ifr"></iframe> <input type="text" name="user" /> <a onclick="submitForm();">提交</a> </form> <script> function submitForm() { document.getElementById('ifr').onload = loadIframe; document.getElementById('f1').submit(); } function loadIframe() { document.getElementById('ifr') } </script> </body> </html>
document.getElementById('ifr')加上参数取不到值,因为HTML标签里面还嵌套了HTML标签(页面)
document.getElementById('ifr').contentWindow
Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
document.getElementById('ifr').contentWindow.document.body这样才能拿到值
<body>返回值</body>
document.getElementById('ifr').contentWindow.document.body.innerText
"返回值"
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> <iframe id="ifr" name="ifr" style="display: none"></iframe> <input type="text" name="user" /> <a onclick="submitForm();">提交</a> </form> <script> function submitForm() { document.getElementById('ifr').onload = loadIframe; document.getElementById('f1').submit(); } function loadIframe() { {# document.getElementById('ifr')#} var content = document.getElementById('ifr').contentWindow.document.body.innerText; alert(content) } </script> </body> </html>
文件上传之原生Ajax
基于Ajax上传文件:
1. XMLHttpRequest
- 原生: 依赖FormData对象(HTML5)
- jQuery: 依赖FormData对象(HTML5)
2. 伪造Ajax
- 兼容性更好
1.原生Ajax实现文件上传,依赖FormData对象(HTML5)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def upload(request): if request.method == "GET": return render(request,'upload.html') else: print(request.POST,request.FILES) #<QueryDict: {'------WebKitFormBoundarymlADIkJ01jWM7uaR\r\nContent-Disposition: form-data': [''], ' name': ['"k1"\r\n\r\nv1\r\n------WebKitFormBoundarymlADIkJ01jWM7uaR--\r\n']}> <MultiValueDict: {}> return HttpResponse('OK')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> {# <div id="container1"></div>#} <script src="/static/jquery-3.2.1.js"></script> <script> function upload1() { var formData = new FormData(); formData.append('k1','v1'); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4){ alert(xhr.responseText); } }; xhr.open('POST','/upload/'); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.send(formData); } </script> </body> </html>
#输出值:(加上请求头 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); )
<QueryDict: {'------WebKitFormBoundary04DkByF1aCOP18ES\r\nContent-Disposition: form-data': [''], ' name': ['"k1"\r\n\r\nv1\r\n------WebKitFormBoundary04DkByF1aCOP18ES--\r\n']}> <MultiValueDict: {}>
输出值:(不加请求头)
<QueryDict: {'k1': ['v1']}> <MultiValueDict: {}> 输出原来的值
拿到文件对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def upload(request): if request.method == "GET": return render(request,'upload.html') else: print(request.POST,request.FILES) return HttpResponse('OK')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> {# <div id="container1"></div>#} <script src="/static/jquery-3.2.1.js"></script> <script> function upload1() { var formData = new FormData(); formData.append('k1','v1'); formData.append('fafafa',document.getElementById('i1').files[0]); {# document.getElementById('i1').files[0]既有普通的文本又有普通文件 #} {# //文件对象#} var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4){ alert(xhr.responseText); } }; xhr.open('POST','/upload/'); {# xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#} xhr.send(formData); } </script> </body> </html>
输出:<QueryDict: {'k1': ['v1']}> <MultiValueDict: {'fafafa': [<InMemoryUploadedFile: QQ图片20170218234431.jpg (image/jpeg)>]}>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def upload(request): if request.method == "GET": return render(request,'upload.html') else: print(request.POST,request.FILES) file_obj = request.FILES.get('fafafa') file_path = os.path.join("static",file_obj.name)#找到文件 with open(file_path,'wb') as f:#打开文件 for chunk in file_obj.chunks(): f.write(chunk)#写文件,上传成功 return HttpResponse(file_path)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> {# <div id="container1"></div>#} <script src="/static/jquery-3.2.1.js"></script> <script> function upload1() { var formData = new FormData(); formData.append('k1','v1'); formData.append('fafafa',document.getElementById('i1').files[0]); {# document.getElementById('i1').files[0]既有普通的文本又有普通文件 #} {# //文件对象#} var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4){ var file_path = xhr.responseText; alert(file_path); {# responseText拿到文件路径 #} } }; xhr.open('POST','/upload/'); {# xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#} xhr.send(formData); } </script> </body> </html>
http://127.0.0.1:8001/static/QQ%E5%9B%BE%E7%89%8720170218234431.jpg 预览文件
通过原生ajax发到后台,但是上传文件需要依赖FormData对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os def upload(request): if request.method == "GET": return render(request,'upload.html') else: print(request.POST,request.FILES) file_obj = request.FILES.get('fafafa') file_path = os.path.join("static",file_obj.name)#找到文件 with open(file_path,'wb') as f:#打开文件 for chunk in file_obj.chunks(): f.write(chunk)#写文件,上传成功 return HttpResponse(file_path)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> <div id="container1"></div> <script src="/static/jquery-3.2.1.js"></script> <script> function upload1() { var formData = new FormData(); formData.append('k1','v1'); formData.append('fafafa',document.getElementById('i1').files[0]); {# document.getElementById('i1').files[0]既有普通的文本又有普通文件 #} {# //文件对象#} var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4){ var file_path = xhr.responseText; alert(file_path); var tag = document.createElement('img'); tag.src = "/" + file_path; 字符串拼接 document.getElementById('container1').appendChild(tag); {# responseText拿到文件路径 #} } }; xhr.open('POST','/upload/'); {# xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#} xhr.send(formData); } </script> </body> </html>
2.jQuery ajax实现文件上传,依赖FormData对象(HTML5)
print(request.POST,request.FILES) <QueryDict: {'k1': ['v1']}> <MultiValueDict: {'fafafa': [<InMemoryUploadedFile: CMDB.jpg (image/jpeg)>]}>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os def upload(request): if request.method == "GET": return render(request,'upload.html') else: print(request.POST,request.FILES) file_obj = request.FILES.get('fafafa') file_path = os.path.join("static",file_obj.name)#找到文件 with open(file_path,'wb') as f:#打开文件 for chunk in file_obj.chunks(): f.write(chunk)#写文件,上传成功 return HttpResponse(file_path)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> <div id="container1"></div> <h1>jQuery Ajax上传文件</h1> <input type="file" id="i2"> <a onclick="upload2();">上传</a> <div id="container2"></div> <script src="/static/jquery-3.2.1.js"></script> <script> function upload1() { var formData = new FormData(); formData.append('k1','v1'); formData.append('fafafa',document.getElementById('i1').files[0]); {# document.getElementById('i1').files[0]既有普通的文本又有普通文件 #} {# //文件对象#} var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4){ var file_path = xhr.responseText; alert(file_path); var tag = document.createElement('img'); tag.src = "/" + file_path; document.getElementById('container1').appendChild(tag); {# responseText拿到文件路径 #} } }; xhr.open('POST','/upload/'); {# xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#} xhr.send(formData); } function upload2() { var formData = new FormData(); formData.append('k1','v1'); {# formData.append('fafafa',document.getElementById('i1').files[0]);#} formData.append('fafafa',$('#i2')[0].files[0]); {# $('#i2') -> $('#2')[0] jQuery对象转成DOM对象 #} {# $(document.getElementById('i1')) DOM对象转成jQuery对象 #} $.ajax({ url: '/upload/', type: 'POST', data: formData, contentType:false, processData:false, success:function (arg) { var tag = document.createElement('img'); tag.src = "/" + arg; $('#container2').append(tag); } }) } </script> </body> </html>
$('#i2') -> $('#2')[0] jQuery对象转成DOM对象 $(document.getElementById('i1')) DOM对象转成jQuery对象
3.伪ajax实现文件上传,兼容性更好
包含两个元素(iframe和Form)
切记:上传一定要在Form表单添加 enctype="multipart/form-data"
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import os def upload(request): if request.method == "GET": return render(request,'upload.html') else: print(request.POST,request.FILES) file_obj = request.FILES.get('fafafa') file_path = os.path.join("static",file_obj.name)#找到文件 with open(file_path,'wb') as f:#打开文件 for chunk in file_obj.chunks(): f.write(chunk)#写文件,上传成功 return HttpResponse(file_path) 返回文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>原生Ajax上传文件</h1> <input type="file" id="i1"> <a onclick="upload1();">上传</a> <div id="container1"></div> <h1>jQuery Ajax上传文件</h1> <input type="file" id="i2"> <a onclick="upload2();">上传</a> <div id="container2"></div> <h1>伪Ajax上传文件</h1> <form id="f1" method="POST" action="/upload/" target="ifr" enctype="multipart/form-data"> <iframe id="ifr" name="ifr" style="display: none"></iframe> <input type="file" name="fafafa" /> <a onclick="upload3();">上传</a> </form> {# <a onclick="upload3();">上传</a>#} <div id="container3"></div> <script src="/static/jquery-3.2.1.js"></script> <script> function upload1() { var formData = new FormData(); formData.append('k1','v1'); formData.append('fafafa',document.getElementById('i1').files[0]); {# document.getElementById('i1').files[0]既有普通的文本又有普通文件 #} {# //文件对象#} var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4){ var file_path = xhr.responseText; alert(file_path); var tag = document.createElement('img'); tag.src = "/" + file_path; document.getElementById('container1').appendChild(tag); {# responseText拿到文件路径 #} } }; xhr.open('POST','/upload/'); {# xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#} xhr.send(formData); } function upload2() { var formData = new FormData(); formData.append('k1','v1'); {# formData.append('fafafa',document.getElementById('i1').files[0]);#} formData.append('fafafa',$('#i2')[0].files[0]); {# $('#i2') -> $('#2')[0] jQuery对象转成DOM对象 #} {# $(document.getElementById('i1')) DOM对象转成jQuery对象 #} $.ajax({ url: '/upload/', type: 'POST', data: formData, contentType:false, processData:false, success:function (arg) { var tag = document.createElement('img'); tag.src = "/" + arg; $('#container2').append(tag); } }) } function upload3() { document.getElementById('ifr').onload = loadIframe; document.getElementById('f1').submit(); } function loadIframe() { var content = document.getElementById('ifr').contentWindow.document.body.innerText; var tag = document.createElement('img'); tag.src = "/" + content; $('#container3').append(tag); } </script> </body> </html>
总结:
1. 用ajax上传文件
伪造的 ajax,因为兼容性更好
2. 发数据(字符串,列表,字典)
- jQuery ajax,写起来更简单,取值更加方便,用 .serialize()取到所有的值.
-如果不用jQuery ajax,可以用 XMLHttpRequest(伪造),但是代码相对多一点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<iframe id="uploadIframe" name="uploadIframe" scrolling="no" height="0px" frameborder="0" style="display:none" src="/blank.html"></iframe> #document == $0 <html> <head> <script type="text/javascript">document.domain='chouti.com'</script> </head> <body> {"result": {"code":"9999", "message":"图片上传成功", "data": {"imgUrl":"http://img2.chouti.com/CHOUTI_975BF40BB28440DBA4827DFD6B375075_W1366H768=420x185.jpg", "identifie":"1499528915973" } } } </body> </html>
上传图片iframe,有个返回值
3. 不要被好看的上传按钮迷惑
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<input type="file" name="imgUrl" id="imgUrl" size="1" hidefocus="true"> #adUploadImgUrl, #imgUrl { border: 0; filter: alpha(opacity=0); background: 0 0; opacity: 0; #当opacity大于0时会出现一个选择框 -moz-opacity: 0; width: 62px; height: 31px; left: 5px; top: 5px\9; position: absolute; cursor: pointer; }
宽度大一点,高度大一点,放在标签大一点,透明度等于0,点开上传,其实都是点的里面那个按钮
position
z-index
JSONP
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def jsonp(request): return render(request,'jsonp.html')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <a onclick="sendMsg();">发送</a> <script src="/static/jquery-3.2.1.js"></script> <script> function sendMsg() { $.ajax({ url: 'http://dig.chouti.com/', #抽屉网 type: "GET", success: function (arg) { console.log(arg); } }) } </script> </body> </html>
XMLHttpRequest cannot load http://dig.chouti.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8001'
is therefore not allowed access.
在浏览器上向别的网址发一个请求, 为什么浏览器禁止了,因为浏览器基于同源策略(请求发过去了,但是没有拿到返回值,由于浏览器的同源策略)
浏览器:同源策略,
- 禁止:Ajax跨域发送请求时,再回来时浏览器拒绝接收
- 允许:script标签没禁止(允许src属性)
不能往别的网址发请求,只能往自己URL发请求
解决这个问题的途径就是JSONP,,通过钻空子, 跳过浏览器的同源策略,
一点发送,head里面就多了一条script数据
script生成的页面会下载到内存里
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function f1(arg) {
alert(arg)
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
f1(123)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <script src="/static/commons.js"></script> <script src="/static/commons2.js"></script> </head> <body> <a onclick="sendMsg();">发送</a> {# <script src="/static/jquery-3.2.1.js"></script>#} <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script> function sendMsg(){ var tag = document.createElement('script'); tag.src = "http://www.baidu.com"; document.head.appendChild(tag); } </script> </body> </html>
访问http://127.0.0.1:8001/jsonp/即弹出窗口
因为script已经加载到内存,然后commons2.js里执行commons.js里的函数.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function list(arg) {
alert(arg)
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <script src="/static/commons.js"></script> {# <script src="/static/commons2.js"></script>#} </head> <body> <a onclick="sendMsg();">发送</a> {# <script src="/static/jquery-3.2.1.js"></script>#} <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script> function sendMsg(){ var tag = document.createElement('script'); tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403"; document.head.appendChild(tag); } </script> </body> </html>
tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403"; 相当于生成一个
<script src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403"> </script>
拿到网页对象了
如果把commons.js改一下内容,然后拿到所有的数据(发一个请求)
JSONP规则:跨域。JSONP的本质是可以远程发请求(没用ajax,完成跨域),然后返回数据.
1.提前定义一个函数
function list(arg){
console.log(arg);
}
2. 发送端(发送请求,调用上面的list函数,list函数传什么值,上面的函数都能接收到):
把数据拼接成script代码,script代码放在html
<script src='http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'></script>
list({......})
createElement('script') 创建一个script标签
function list(arg) {
console.log(arg) #arg是一个字典
}
出现一连串的对象
posted on 2017-07-07 16:03 bigdata_devops 阅读(325) 评论(0) 编辑 收藏 举报