基于python-flask搭建后台,HTML+CSS+JS(jQuery)写前端的web全栈开发(三)——3.1 uploadfiles上传图片到后台(显示进度)处理并返回显示

    前面小编说这个项目有两个页面,一个是sketch.html定义的介绍实验室项目(包括abstract,paper,framework,code,results等)的纯前端页面;另一个则是demo.html定义的用户成果体验页面。

    通过点击在sketch.html里的按钮进入另一个页面,要怎么实现呢?

    上图是sketch.html里的页面跳转按钮!

    其定义代码在sketch.html如下:

<head>
    ……
    <h2>Demo</h2>
    <dd></dd>
    <dd>
        Click <a href="{{ url_for('gotoDemo') }}" style="border: #FF8104 solid 1px; border-radius: 15px; color: #FF8014; text-decoration: none; padding-left: 15px; padding-right: 15px;">here</a> to have a join!
     </dd>
    ……
</head>

    注意,这里我们并不是一个真正的<input type="button"/>按钮,而是一个<a/>链接。通过对 href 的定义,在“{{ url_for('函数名称') }}”来将其绑定到后台sketch.py的一个有着相同函数名的函数上!

    后台的代码如下

@app.route('/sketch/demo')
def gotoDemo():
    return render_template('demo.html')

    这里要注意的有两点:

        1)路由的设置,是区别于其他已定义路由的,因为一个页面对应惟一一个路由(注、;路由的设置必须以‘/’开头);

        2)后台函数返回我们希望看到的新的html页面。

 

步入正题:

    首先为大家展示一下我们的demo页面组成,其中主要的是

        1)“left”:用来展示选中的处理前的图片;

        2)“right”:用来展示对应的处理后的图片;

        3)“select image”:点击它就会调出windows的文件选择窗口;当我们选中图片后,选中的文件就会自动上传了!这一点很重要,换句话说,submit按钮是没有用途的,但实际应用中我们需要这么一个按钮来帮助我们完善一个完整的用户体验;

        4)介于image串口和select按钮之间的灰色长条,就是我们的进度条了!

1. 使用大神的插件

    网址是:https://github.com/blueimp/jQuery-File-Upload

    这是一个灰常灰常经典而实用的插件了,我们需要下载整个工程,但这里小编仅是使用最简单的版本

    其中我们需要的只是以下几个文件:

        ① jQuery-File-Upload-master\css\jquery.fileupload.css

        ② jQuery-File-Upload-master\css\style.css

        ③ jQuery-File-Upload-master\js\jquery.iframe-transport.js

        ④ jQuery-File-Upload-master\js\jquery.fileupload.js 

        ⑤ jQuery-File-Upload-master\js\vendor\jquery.ui.widget.js

        ⑥ 额外下载jquery-min.js文件

    将其复制到对应的“static/css”或者“static/js”目录下。

    在实际应用中,我们还需要引入下面两个关于Bootstrap的链接。

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

2. 小白的实现

    完整的demo.html代码如下

<!-- demo.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
	
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/jquery.fileupload.css') }}">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/demo.css') }}">
	<!-- 这个是我额外自己添加的.css文件 -->

</head>
    <body>
    <script src="{{ url_for('static', filename='js/jquery-3.2.1.min.js') }}"></script>
	<!-- 这里我下载的是jquery-3.2.1.min.js -->
    <script src="{{ url_for('static', filename='js/vendor/jquery.ui.widget.js') }}"></script>
    <script src="{{ url_for('static', filename='js/jquery.iframe-transport.js') }}"></script>
    <script src="{{ url_for('static', filename='js/jquery.fileupload.js') }}"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
	
    <!-- the title bar 标题 -->
    <h1 style="padding-left: 30px; padding-right: 30px; padding-top: 15px; padding-bottom: 15px;">
        <b>Sketch Simplification</b>
    </h1>
	
    <dd></dd>
    <br/><br/>
    <!-- the image windows 图片窗口 -->
    <div>
        <img src="" id="left" name="left" style="padding: 10px; width: 50%; float: left; border: #f48401 solid 1px;"/>
        <img src="" id="right" name="right" style="padding: 10px; width: 50%; border: #f48401 solid 1px;"/>
    </div>
    <br/>
	
    <!-- the process bar 进度条 -->
    <div id="progress" class="progress">
        <div class="progress-bar progress-bar-success" style="background-color: #f48401;"></div>
    </div>
    
    <!-- the two buttons 两个按钮-->
    <div>
        <span class="btn btn-success fileinput-button" style="background-color: #f48401; border: none">
            <i class="glyphicon glyphicon-plus"></i>
            <span>Select images...</span>
            <input id="fileupload" type="file" name="files[]" multiple accept="image/png, image/jpg, image/jpeg">
        </span>	<!-- 选择(并上传)按钮 -->
		
        <input type="button"
               style="color: white;
                font-size: 15px;
                background-color: #ffaf53;
                border-radius: 8px;
                padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 20px;
                border: none;"
               id="submit";
               value="Submit">	<!-- 提交按钮 -->
    </div>
    

    <script type="text/javascript">
        $(function () {		// 标准写法,表示包含在function(){}之内的函数和变量都必须是在页面完全加载完毕后才发挥作用
            'use strict';	// 标准写法,JS的格式要求
			
			
            var url = 'http://127.0.0.1:5000/sketch/upload';	
	    // ** 自定义一个新的url,我们假设有一个潜藏的页面叫作‘http://127.0.0.1:5000/sketch/upload’
	    // ** 我们希望在那个虚拟的地方进行与后台的数据交换,
	    // ** 因此,我们后台的对应函数的路由应该设置为“ @app.route('/sketch/upload') ”
			
	    // ** 下面我们打算构建一组东西,是给file按钮准备的,
	    // *  包括了:fileupload,prop,
	    // *  第一部分的fileupload包括了:url, 信息交互的数据类型,done,progressall
            $('#fileupload').fileupload({
                url: url,
                dataType: 'json',// 数据交互的类型
				
		// done表示当接收到后端反馈的信息是要做的动作
                done: function (e, data) {
                    var filepath = "", filepath_ = "";
                    $.each(data.result.files, function (index, file) {
                        $('<p style="display: none"/>').text(file.name).appendTo(document.body);
                        filepath = file.filepath;
                        filepath_ = file.filepath_;
                    });
                    $('#left').attr('src', '../' + filepath);
                    $('#right').attr('src', '../' + filepath_);

                },// 这一部分小编会结合后端的函数一起讲解
				
		// progressall表示在选择好文件后上传文件过程中要做的动作
                progressall: function (e, data) {
		    // 显然这是对进度条做宽度变化
                    var progress = parseInt(data.loaded / data.total * 100, 10);
                    $('#progress .progress-bar').css(
                        'width',
                        progress + '%'
                    );
                }
            }).prop('disabled', !$.support.fileInput)
                .parent().addClass($.support.fileInput ? undefined : 'disabled');
            
        });
    </script>
    </body>
</html>

    这里还希望大伙们理解,把部分css代码和js代码杂糅进来了,因为写的有些匆忙敲打。下面我们着重讲解一下js那部分接收代码!

    正如小编前面提到的,当我们确定选择的图片后,文件就已经上传了,所以在提交按钮的js函数里才会有一个done的函数来解决“当传输完成并且顺利获得后台的反馈时采取什么样的动作”。

    我们的思路是,先在后台把获得的图片读取并暂时根据本地时间命名、保存下来,完了后我们在重新读取,进行一系列图像处理,而后再把结果暂时存储下来,最后我们只需要返回原图片结果图片的两条路径既可,再通过JS对<img/>图片标签进行更新。

sketch.py新增的函数

@app.route('/sketch/upload', methods=['POST', 'GET'])
def upload():
    if request.method == 'POST':
        f = request.files['files[]']

        # print(f)
        filename = f.filename	# 获取接收到的文件名
        # print(filename)
        minetype = f.content_type# 文件类型
        # print(minetype)

        now_time = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')	# 获取本地时间,进行图片重命名
        dir = 'static/temp-img/rough/' + now_time	
	# ‘static/temp-img/rough/’是我们预设置的路径,用来暂时存储原图片,于是我们构造了图片的存储路径和名字
		
        os.makedirs(dir)
        filepath = dir +"/" + now_time + "." + filename.split(".")[1]	# 但别忘记我们还需要获得图片格式(扩展名,可能是.jpg,.png等)

        f.save(filepath)	# 将文件存储下来

        img = Image.open(filepath).convert('L')	# 重新读出图片
        img_ = F(img)							# 并对齐进行某种处理,返回结果图片

        filepath_ = "static/temp-img/simplified/model_iter_39000.npz/" + now_time + "." + filename.split(".")[1]
	# ‘static/temp-img/simplified/’也是我们预设置的路径,用来暂时存储结果图片
	img_.save(filepath_)
        
	# 最后我们就可以返回对应的路径啦
        return simplejson.dumps({
            "files":
                [{
                    "name": filename,
                    "mintype": minetype,
                    "filepath": filepath,
                    "filepath_": filepath_
                }]
        })
    else:
        return render_template('demo.html')

    好了,我们发现,如果成功的话,就会把原图片和结果图片在后台的路径传回前台,那么接下来我们要做的也就是通过说“更新img的src值来迫使前端以获取html所需图片为理由更新并显示图片”

    最后我们再来看前面那一段done的内容,就很好懂了吧!

done: function (e, data) {	// 这里的data正是后台传回的数据
    var filepath = "", filepath_ = "";
    $.each(data.result.files, function (index, file) {
		$('<p style="display: none"/>').text(file.name).appendTo(document.body);
        filepath = file.filepath;
        filepath_ = file.filepath_;
    });// 因为可能是多文件相传,但我们只选择最后一个文件的名字
	
    $('#left').attr('src', '../' + filepath);
    $('#right').attr('src', '../' + filepath_);
    // jQuery风格的 html 标签属性更新

    document.getElementById('right').style.visibility = 'hidden';
},

    最后是效果图啦,

    以及后期经过完善后,实现的效果。

总结

    至此,我们了解了基于bootstrap的文件上传,和前端与flask后端做数据交互的一种方式。

    下一篇,我们将再了解另外一中前后台交互方式!

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值