首页 > 解决方案 > 通过对烧瓶的 ajax 调用从另一个驱动器更改图像源

问题描述

当我用另一个驱动器中的图像单击图像时,我想更改图像。为此,我创建了这个 python 函数:

@main.route('/tester/', methods=['GET', 'POST'])
def tester():
    if request.method == "GET":
        test_img = "D:\TBV_Data\MS_CO_Front_20120403_140154_0001140_006.png"
        return send_file(test_img, mimetype='image/png')  

我通过以下函数请求此数据:

function testFunc() {
    $.ajax({
        url: '/tester', //server url
        type: 'GET',    //passing data as post method
        async: false,
        success: function(data) {
            $("#myimage9").attr("src", "data:image/png;base64," + data);
        },
    });
};

不幸的是,图像的“src”结果是一堆奇怪的数据:

<img id="myimage9" src="data:image/png;base64,�PNG
IHDR�I!�IDATx���׮mK�&amp;amp;�}�;��morg��c�V��)C�� B��.�(z�� ��� ��*��B�y2�I��^~��]D�1��ÁDb�9��&amp;�E����o-���OZl��/_���NJ��%�%�т���6�ݴw�~��EE���-�[p�z^3Y����8��#�

我可以想象我没有正确编码图像。有人可以告诉我我做错了什么吗?

编辑:我尝试将数据编码为base64:

function utoa(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
};

不幸的是,这只会将数据更改为以下内容,但不会显示图像:

<img id="myimage9" src="data:image/png;base64,/VBORw0KGgoAAAANSUhEUgAABRAAAAP9CAIAAAAUSSH9AAEAAElEQVR4/f397m1L/Sb9ff0OO/39bW9yZ/39Y/0dVv39KUP9/SBC/f0u/Sh6A

标签: pythonjqueryajaxflask

解决方案


在服务器端,filename为您的路由添加一个变量:

import os
from flask import request, send_from_directory

IMAGE_DIR = r"D:\TBV_Data"

@main.route('/tester/<filename>')
def tester(filename):
    return send_from_directory(IMAGE_DIR, filename)

这使用该send_from_directory功能来确保客户端无法通过输入包含类似内容的文件名从指定目录之外\..\下载文件(这称为“目录遍历攻击”)。

在客户端:

function testFunc(selector, filename) {
    $(selector).attr("src", "/tester/" + encodeURIComponent(filename) );
}

使用encodeURIComponent()is 良好的风格并防止包含特殊字符的文件名出现问题。浏览器会在其src属性发生变化时立即请求该图像,此处无需通过 Ajax 进行任何操作。


send_file()单独防止目录遍历攻击涉及更多:

filepath = os.path.realpath(os.path.join(IMAGE_DIR, filename))
if os.path.commonprefix([filepath, IMAGE_DIR]) != IMAGE_DIR:
    abort(404)

return send_file(filepath)

Windows 上的文件路径不区分大小写,因此IMAGE_DIR应包含路径的实际大小写,否则此测试将失败。


推荐阅读