在表單中我們獲取用戶提交的數據,使用的是get_argument,復選框使用的是get_arguments,但是文件的不一樣,文件的使用request.files。
form文件上傳
html代碼:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>上傳文件</title>
</head>
<body>
<form id="my_form" name="form" action="/index" method="POST" enctype="multipart/form-data" >
<input name="fff" id="my_file" type="file" />
<input type="submit" value="提交" />
</form>
</body>
</html>
注意:
form文件上傳,一定要在form表單上設置enctype的參數。enctype="multipart/form-data"。不然上傳無法成功。
python代碼:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
def post(self, *args, **kwargs):
file_metas = self.request.files["fff"]
# print(file_metas)
for meta in file_metas:
file_name = meta['filename']
with open(file_name,'wb') as up:
up.write(meta['body'])
settings = {
'template_path': 'template',
}
application = tornado.web.Application([
(r"/index", MainHandler),
], **settings)
if __name__ == "__main__":
application.listen(8000)
tornado.ioloop.IOLoop.instance().start()
說明:
1、代碼中self.request封裝了所有發送過來請求的內容。
2、self.request.files:可以獲取上傳文件的所有信息。此方法獲取的是一個生成器,內部是由yield實現的,因此我們在利用此方法返回的對象的時候,不能通過下標獲取里面的對象,只能通過迭代的方法。
3、迭代出來的對象的filename:就表示上傳文件的文件名。
4、迭代出來的對象的body:表示上傳文件的內容。獲取的文件內容是字節形式的。
ajax上傳文件
- 原生ajax
- jquery
原生ajax上傳文件
html代碼:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="file" id="img" />
<input type="button" onclick="UploadFile();" />
<script>
function UploadFile(){
var fileObj = document.getElementById("img").files[0];
var form = new FormData();
form.append("k1", "v1");
form.append("fff", fileObj);
var xhr = new XMLHttpRequest();
xhr.open("post", '/index', true);
xhr.send(form);
}
</script>
</body>
</html>
說明:
代碼中利用原生的ajax進行文件上傳。
關鍵點:
1、獲取文件對象,通過files[0],獲取當前上傳的文件對象。
2、通過FormData(),實例化一個對象form對象。
3、然后將要傳遞的參數,文件以鍵和值以逗號分隔的形式append到form對象中去。
4、然后將整個form對象發送到服務端。
注意:
后台代碼和上面的代碼一樣,不變。注意接收的文件名要同步。
jquery文件上傳
html代碼:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="file" id="img" />
<input type="button" onclick="UploadFile();" />
<script>
function UploadFile(){
var fileObj = $("#img")[0].files[0];
var form = new FormData();
form.append("k1", "v1");
form.append("fff", fileObj);
$.ajax({
type:'POST',
url: '/index',
data: form,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success: function(arg){
console.log(arg);
}
})
}
</script>
</body>
</html>
說明:
1、和原生的一樣,都是顯得獲取當前上傳文件的對象。files[0];然后實例化form對象,將要傳遞的內容append到實例化的對象form中。
2、后台代碼同前,注意字段名對應。
關鍵點:
processData:false和contentType:false。這2個是關鍵。
默認的jquery會將我們上傳的數據做部分處理。上面兩段代碼,就是告訴jquery不要處理我們的文件,不然會將我們的文件處理得不完整。
iframe文件上傳
原生的ajax和jquery上傳的時候,我們都是通過實例化一個form對象來進行文件的上傳。但是實例化這個form的對象並不是所有的瀏覽器都存在,比如低版本的IE就可能沒有合格FormData對象,那上面的方法就存在兼容性,沒有form對象就不能發送。因此的使用一個兼容性更好的來進行操作,iframe。
html代碼:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form id="my_form" name="form" action="/index" method="POST" enctype="multipart/form-data" >
<div id="main">
<input name="fff" id="my_file" type="file" />
<input type="button" name="action" value="Upload" onclick="redirect()"/>
<iframe id='my_iframe' name='my_iframe' src="" class="hide"></iframe>
</div>
</form>
<script>
function redirect(){
document.getElementById('my_iframe').onload = Testt;
document.getElementById('my_form').target = 'my_iframe';
document.getElementById('my_form').submit();
}
function Testt(ths){
var t = $("#my_iframe").contents().find("body").text();
console.log(t);
}
</script>
</body>
</html>
關鍵點:
1、document.getElementById('my_form').target = 'my_iframe':這段代碼就是獲取iframe標簽。
target就是目標,只要給form設置了target的話,form提交的時候,就會提交到這個target指定的目標上。所以上面的代碼表示只要form提交,就會提交到iframe上去。
2、當iframe操作完后會執行Testt方法,Testt方法就是獲取后台返回的信息,並打印。
