效果图:
使用iframe实现无刷新上传图片首先需要在iframe指定下form,action指定为要提交的地址,注意form表单是不能嵌套的 后台: js:
代码展示:
前端:
{% extends "common/layout_main.html" %}
{% block content %}
<div class="row border-bottom">
<div class="col-lg-12">
<div class="tab_title">
<ul class="nav nav-pills">
<li class="current">
<a href="{{ buildUrl('/food/index') }}">美食列表</a>
</li>
<li>
<a href="{{ buildUrl('/food/cat') }}">分类列表</a>
</li>
</ul>
</div>
</div>
</div>
<div class="row mg-t20 wrap_food_set" style="">
<div class="col-lg-12" style="">
<h2 class="text-center">设置</h2>
<div class="form-horizontal m-t" style="">
<div class="form-group">
<label class="col-lg-2 control-label">分类:</label>
<div class="col-lg-10">
<select name="cat_id" class="form-control select2-hidden-accessible select2-container" tabindex="-1"
aria-hidden="true">
<option value="0">请选择分类</option>
<option value="8">111</option>
<option value="8">川菜</option>
<option value="8">粤菜</option>
<option value="8">湘菜</option>
</select>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-lg-2 control-label">名称:</label>
<div class="col-lg-10">
<input type="text" class="form-control" placeholder="请输入名称" name="name" value="">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-lg-2 control-label">价格:</label>
<div class="col-lg-10">
<input type="text" class="form-control" placeholder="请输入售价" name="price" value="">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-lg-2 control-label">封面图:</label>
<div class="col-lg-10">
<form class="upload_pic_wrap" target="upload_file" enctype="multipart/form-data" method="POST" action="{{ buildUrl('/upload/pic') }}">
<div class="upload_wrap pull-left">
<i class="fa fa-upload fa-2x"></i>
<input type="file" name="pic" accept="image/png, image/jpeg, image/jpg,image/gif">
</div>
</form>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group" style="">
<label class="col-lg-2 control-label">描述:</label>
<div class="col-lg-10">
<textarea id="editor" name="summary" style="height: 300px;"></textarea>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-lg-2 control-label">库存:</label>
<div class="col-lg-2">
<input type="text" name="stock" class="form-control" value="1">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label class="col-lg-2 control-label">标签:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="tags" value="">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-lg-4 col-lg-offset-2">
<input type="hidden" name="id" value="0">
<button class="btn btn-w-m btn-outline btn-primary save">保存</button>
</div>
</div>
</div>
</div>
</div>
<iframe name="upload_file" class="hidden"> </iframe>
{% endblock %}
{% block css %}
{# 导入 select2#}
<link href="{{ buildStaticUrl('/plugins/select2/select2.min.css')}}" rel="stylesheet">
{# 导入 tagsinput#}
<link href="{{ buildStaticUrl('/plugins/tagsinput/jquery.tagsinput.css ')}}" rel="stylesheet">
{% endblock %}
{% block js %}
{# select2 导入js#}
{# <script src="{{ buildStaticUrl('/plugins/select2/jquery.select2.js ')}}"></script>#}
<script src="{{ buildStaticUrl('/plugins/select2/select2.pinyin.js')}}"></script>
{# <script src="{{ buildStaticUrl('/plugins/select2/zh-CN.js ')}}"></script>#}
{# 导入 tagsinput#}
<script src="{{ buildStaticUrl('/plugins/tagsinput/jquery.tagsinput.min.js ')}}"></script>
{#ueditor富文本编辑器#}
<script src="{{ buildStaticUrl('/plugins/ueditor/ueditor.config.js ')}}"></script>
<script src="{{ buildStaticUrl('/plugins/ueditor/ueditor.all.js ')}}"></script>
<script src="{{ buildStaticUrl('/plugins/ueditor/lang/zh-cn/zh-cn.js ')}}"></script>
<script src="{{ buildStaticUrl('/js/food/set.js ')}}"></script>
{# <script src="{{ buildStaticUrl('/js/jquery-2.1.1.js ')}}"></script>#}
{% endblock %}
后台:
@route_upload.route("/pic",methods=["POST","GET"])
def upload_pic():
files_pic=request.files
files_pic= files_pic["pic"] if "pic" in files_pic else None
callback_target="window.parent.upload"
if files_pic is None:
return "<scrpit type='text/javascript'>{0}.error('{1}')</scrpit>".format(callback_target,"图片长传失败")
ret=UploadService.UploadByFile(files_pic)
if ret["code"] !=200:
return "<script type='text/javascript'>{0}.error('{1}')</script>".format(callback_target,"图片长传失败")
return "<script type='text/javascript'>{0}.success('{1}')</script>".format(callback_target,ret["data"]["file_key"])
图片处理代码:
import os,stat
import uuid
from werkzeug.utils import secure_filename
from application import app, db
from common.libs.Helper import getGreated_date
from common.models.Images import Image
class UploadService:
@staticmethod
def UploadByFile(file):
config_upload=app.config["UPLOAD"]
resp={"code":200,"msg":"操作成功","data":{}}
filename=secure_filename(file.filename)
ext=filename.rsplit('.',1)[1]
if not ext in config_upload['ext']:
resp["code"]=-1
resp["msg"]="不允许的扩展类型文件"
return resp
root_path=app.root_path.replace("\\","/")+config_upload['prefix_path']
print(app.root_path)
file_dir=getGreated_date()
save_dir=root_path+"/"+file_dir
if not os.path.exists(save_dir):
os.mkdir(save_dir)
os.chmod(save_dir,stat.S_IRWXU | stat.S_IRGRP |stat.S_IRWXO)
file_name=str(uuid.uuid4()).replace("_","")+"."+ext
file.save("{0}/{1}".format(save_dir,file_name))
module_image=Image()
module_image.file_key=file_dir+"/"+file_name
module_image.created_time=getGreated_date()
db.session.add(module_image)
try:
db.session.commit()
except Exception as e:
resp["code"] = -1
resp["msg"] = "服务器异常,保存图片失败!"
return resp
resp["data"]={
"file_key":file_dir+"/"+file_name
}
return resp
JS:
var upload = {
error: function (msg) {
common_ops.alert(msg);
},
success: function (file_key) {
if (!file_key) {
return;
}
var html = '<img src="' + common_ops.buildPicUrl(file_key) + '"/>'
+ '<span class="fa fa-times-circle del del_image" data="' + file_key + '"></span>';
if ($(".upload_pic_wrap .pic-each").size() > 0) {
$(".upload_pic_wrap .pic-each").html(html);
} else {
$(".upload_pic_wrap").append('<span class="pic-each">' + html + '</span>');
}
food_set.delete_img();
}
};
var food_set={
init:function () {
this.eventBind();
this.initEditor();
},
eventBind:function () {
$(".wrap_food_set .upload_pic_wrap input[name=pic]").change(function () {
$(".wrap_food_set .upload_pic_wrap").submit();
});
$(".wrap_food_set select[name=cat_id]").select2({
language: "zh-CN",
width: '100%'
});
$(".wrap_food_set input[name=tags]").tagsInput({
width:'auto',
height: 20
});
},
initEditor:function () {
var that=this;
that.ue = UE.getEditor('editor', {
toolbars: [
['undo', 'redo', '|',
'bold', 'italic', 'underline', 'strikethrough', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', '|', 'rowspacingtop', 'rowspacingbottom', 'lineheight'],
['customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
'directionalityltr', 'directionalityrtl', 'indent', '|',
'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
'link', 'unlink'],
['imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
'insertimage', 'insertvideo', '|',
'horizontal', 'spechars', '|', 'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols']
],
enableAutoSave: true,
saveInterval: 60000,
elementPathEnabled: false,
zIndex: 4,
serverUrl: common_ops.buildUrl('/upload/ueditor')
});
},
delete_img:function () {
$(".upload_pic_wrap .del_image").unbind().click(function () {
$(this).parent().remove();
})
}
};
$(document).ready(function () {
food_set.init();
$('.singleSelect').select2();
});
|