通常前端页面中,上传文件通过form表单提交,提交成功后重定向到列表或详情页面。
有一个名为ajaxFileUpload的JQuery插件可以利用iframe来实现前端页面中异步上传文件。
比如上文OCR文字识别例子中,当我们在页面点击选择文件按钮,异步上传身份证照片,上传成功后显示在页面中,然后前端调用百度AI的身份证识别接口返回该身份证的记录各字段信息,然后检查无误后,在页面中再确认添加识别结果到数据库。
看一下html代码和js代码
可以看到,此插件只需要上传url和文件上传input的id就可以使用。当上传文件文本框变化时,就立即调用异步上传,上传成功后,后台会生成一个id并返回,根据这个id生成上传到服务器的文件的url,(这里是图片,可以立即显示在页面中),设置上传文件的input的data-value为这个id,当提交整个表单时,将这个文件id保存在数据库中,根据它找到这个表单中上传文件的地址。
前端代码如下:
代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>合同管理系统</title>
<!-- Bootstrap core CSS -->
<link href="static/lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="static/lib/bootstrap/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="static/css/dashboard.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="static/lib/bootstrap/assets/js/ie-emulation-modes-warning.js"></script>
<link href="static/lib/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script id="detailTemplate" type="text/template">
<div class="row">
<div class="col-md-4">
<p><b>姓名</b>: <%=name%></p>
<p><b>性别</b>: <%=gender%></p>
<p><b>民族</b>: <%=group%></p>
<p><b>出生</b>: <%=birth%></p>
<p><b>住址</b>: <%=address%></p>
<p><b>公民身份号码</b> <%=ID%></p>
</div>
<div class="col-md-8">
<img src="static/IDPics/<%=birth '_' ID%>.jpg" class="img-responsive" alt="Responsive image">
</div>
</div>
</script>
<script id="previewTemplate" type="text/template">
<p><b>姓名</b>: <%=name%></p>
<p><b>性别</b>: <%=gender%></p>
<p><b>民族</b>: <%=group%></p>
<p><b>出生</b>: <%=birth%></p>
<p><b>住址</b>: <%=address%></p>
<p><b>公民身份号码</b> <%=ID%></p>
</script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">欢迎你,管理员</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">总览</a></li>
<li><a href="#">查询</a></li>
<li><a href="#">模板管理</a></li>
<li><a href="#">身份证原件管理</a></li>
<li><a href="#">修改密码</a></li>
<li><a href="#">退出</a></li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li><a href="index.html">总览 <span class="sr-only">(current)</span></a></li>
<li><a href="files.html">合同查询</a></li>
<li><a href="docs.html">模板管理</a></li>
<li class="active"><a href="query.html">身份证原件管理</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">修改密码</a></li>
<li><a href="">退出</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header">身份证查询</h1>
<table id="table" data-detail-view="true"
data-detail-formatter="detailFormatter" data-pagination="true"
data-search="true">
<thead>
<tr>
<th data-field="id">序号</th>
<th data-field="name">姓名</th>
<th data-field="gender">性别</th>
<th data-field="group">民族</th>
<th data-field="birth">出生</th>
<th data-field="address">住址</th>
<th data-field="ID">公民身份号码</th>
</tr>
</thead>
</table>
<div class="row">
<div class="col-xs-6 col-md-3">
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default">修改</button>
<button type="button" class="btn btn-default">删除</button>
<button type="file" class="btn btn-default">添加</button>
</div>
</div>
<div class="col-xs-6 col-md-3">
<input type="file" name="ID" id="ID" required data-type="jpg" onchange="javascript:ajaxFileUpload(this)">
<p class="help-block">上传身份证照片.</p>
<button type="file" class="btn btn-default" id="addPic">添加识别结果</button>
</div>
<div class="col-xs-6 col-md-3">
<img id="idcardPreview" style="display:none;" src="" class="img-responsive" alt="身份证照片">
</div>
<div class="col-xs-6 col-md-3">
<div id="words"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="static/lib/jquery.js"></script>
<script src="static/lib/underscore.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"></script>')</script>
<script src="static/lib/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Just to make our placeholder images work. Don't actually copy the next line! -->
<script src="static/lib/bootstrap/assets/js/vendor/holder.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="static/lib/bootstrap/assets/js/ie10-viewport-bug-workaround.js"></script>
<script src="static/lib/bootstrap-table/dist/bootstrap-table.min.js"></script>
<script src="static/lib/ajaxfileupload.js" crossorigin="anonymous"></script>
<script>
var $table = $('#table')
$(function() {
$.get('/getIdcards',function(data){
var data=data['result'];
$table.bootstrapTable({data: data.map((x,i)=>{x['id']=i 1;return x;})});
})
})
var detailTemplate=_.template($('#detailTemplate').html());
var previewTemplate=_.template($('#previewTemplate').html());
function detailFormatter(index, row) {
return detailTemplate(row)
}
function ajaxFileUpload(fileElement)
{
console.log($(fileElement).attr('id'));
var id=$(fileElement).attr('id');
console.log($(fileElement).data('type'));
var type=$(fileElement).data('type');
$.ajaxFileUpload
({
url: 'ajaxUpload?type=' $(fileElement).data('type') '&id=' $(fileElement).attr('id'),
secureuri: false,
fileElementId: $(fileElement).attr('id'),
dataType: 'application/json',
success: function (data, status) {
if(typeof(data)=='string')
{
data=$.parseJSON($(data).text())
}
$(fileElement).data('value',data['result']);
$('input#' id).data('value',data['result']);
$.get('getIdcard',{id:data['result']},function(data){
console.log(data);
if(data.error==0){
var result=data.result;
var row={"name":result.姓名.words,"gender":result.性别.words,"group":result.民族.words,"birth":result.出生.words,"address":result.住址.words,"ID":result.公民身份号码.words}
$('#words').html(previewTemplate(row));
$('#idcardPreview').show();
$('#addPic').removeClass('btn-default').addClass('btn-success');
}
else{
$('#words').html('识别错误,请检查你上传的是身份证正面照片!');
$('#addPic').addClass('btn-default').removeClass('btn-success');
}
});
console.log($(fileElement).data('value'));
$('#idcardPreview').attr('src','static/idcards/' data['result'] '.jpg')
}
});
}
</script>
</body>
</html>
这里后台代码是使用Python的tornado框架写的,代码如下:
代码语言:python代码运行次数:0复制# -*- coding:utf-8 -*-
import os
import math
import random
import uuid
import json
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options
from baidu import *
import json
define('port',default=8094,help='run on the given port',type=int)
class cross_originAllowed_Handler(tornado.web.RequestHandler):
def initialize(self):
self.set_header('Access-Control-Allow-Origin','*')
self.set_header('Access-Control-Allow-Methods','POST,GET')
self.set_header('Access-Control-Max-Age',1000)
self.set_header('Access-Control-Allow-Headers','*')
class getIdcardHandler(tornado.web.RequestHandler):
def get(self):
idCardFile=self.get_argument('id',None)
filePath=os.path.join('./static/idcards',idCardFile '.jpg')
result=getIdcard(access_token,filePath)
if(result==None):
self.write({'error':1})
return
self.write({'result':result,'error':0})
class ajaxUploadHandler(tornado.web.RequestHandler):
def post(self):
fileType=self.get_argument('type',None)
fileId=self.get_argument('id',None)
#self.write({'fileType':fileType,'fileID':fileId})
#return
self.set_header('Content-Type','application/json')
if not self.request.files.has_key(fileId):
self.write({'error':"必须上传文件"})
return
attachFile=self.request.files[fileId][0]
#self.set_header('Content-Type','text/html')
if(len(attachFile.body)>1024*1024*10):
self.write({'error':"文件大小不能超过10M"})
return
fileName=str(uuid.uuid1())
targetDir=os.path.join('./static/idcards')
if(not os.path.exists(targetDir)):
os.mkdir(targetDir)
with open(os.path.join('./static/idcards',fileName "." fileType),'wb') as f:
f.write(attachFile.body)
self.write({'result':fileName})
return
class getIdcardsHandler(tornado.web.RequestHandler):
def get(self):
data=[{"name":"徐乐","gender":"男","group":"汉","birth":"19661102","address":"安徽省宿州市埇桥区朱仙庄镇","ID":"652901196611026716"},{"name":"常涛","gender":"男","group":"汉","birth":"19970601","address":"河北省邯郸市肥乡县肥乡镇","ID":"411526199706013217"},{"name":"陈朋涛","gender":"男","group":"汉","birth":"19890601","address":"山东省滕州市龙阳镇","ID":"532101198906010015"},{"name":"杨朋朋","gender":"男","group":"汉","birth":"19960111","address":"黑龙江省海伦市海伦镇","ID":"310228199601115411"},{"name":"王飞","gender":"女","group":"汉","birth":"19920818","address":"辽宁省大连市甘井子区","ID":"522530199208180048"}]
self.write({'result':data})
class indexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
class idcardsHandler(tornado.web.RequestHandler):
def get(self):
self.render('idcards.html')
class docsHandler(tornado.web.RequestHandler):
def get(self):
self.render('docs.html')
if __name__=='__main__':
global access_token
access_token=getAccess_Token('your ak','your sk')
tornado.options.parse_command_line()
app=tornado.web.Application(
handlers=[
(r'/',indexHandler),
(r'/index.html',indexHandler),
(r'/ajaxUpload',ajaxUploadHandler),
(r'/getIdcard',getIdcardHandler),
(r'/idcards.html',idcardsHandler),
(r'/getIdcards',getIdcardsHandler),
(r'/docs.html',docsHandler),
],
template_path=os.path.join(os.path.curdir,'templates'),static_path=os.path.join(os.path.curdir,'static'),cookie_secret='miaojiyue',debug=True)
http_server=tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()