Reputation: 278
I want to change an image when I click on it with an image from another drive. For this I created this python function:
@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')
I request this data by the following function:
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);
},
});
};
The outcome of the "src" of the image is, unfortunately, a load of weird data:
<img id="myimage9" src="data:image/png;base64,�PNG
IHDR�I!�IDATx���mK�&�}�;��morg��c�V��)C�� B��.�(z�� ��� ��*��B�y2�I��^~��]D�1��ÁDb�9��&�E����o-���OZl��/_���NJ��%�%�т���6�ݴw�~��EE���-�[p�z^3Y����8��#�
I can imagine that I didn't encode the image correctly. Could somebody please tell me what I am doing wrong?
EDIT: I tried to encode the data to base64 with:
function utoa(str) {
return window.btoa(unescape(encodeURIComponent(str)));
};
This will unfortunately just changes the data to the following, but will not show the image:
<img id="myimage9" src="data:image/png;base64,/VBORw0KGgoAAAANSUhEUgAABRAAAAP9CAIAAAAUSSH9AAEAAElEQVR4/f397m1L/Sb9ff0OO/39bW9yZ/39Y/0dVv39KUP9/SBC/f0u/Sh6A
Upvotes: 1
Views: 742
Reputation: 338148
On the server side, add a filename
variable to your route:
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)
This uses the send_from_directory
function to make sure that the client cannot download files from outside the designated directory by entering filenames that contain things like \..\
(this is known as "directory traversal attack").
And on the client side:
function testFunc(selector, filename) {
$(selector).attr("src", "/tester/" + encodeURIComponent(filename) );
}
The use of encodeURIComponent()
is good style and prevents problems with filenames that contain special characters. The browser will request the image as soon as its src
attribute changes, there is no need to do anything via Ajax here.
Preventing a directory traversal attack with send_file()
alone is a bit more involved:
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)
File paths on Windows are case-insensitive, so IMAGE_DIR
should contain the actual case of the path, otherwise this test will fail.
Upvotes: 1
Reputation: 278
Solved:
function testFunc(args) {
selector = args.data[0];
filename = args.data[1];
var obj = JSON.stringify({"data" : filename});
console.log(obj);
$.ajax({
url: '/tester2/', //server url
type: 'GET', //passing data as post method
data: obj,
async: false,
success: function(data) {
$(selector).attr("src", "/tester2/");
},
});
};
I was assigning the raw data to the src attribute, but I needed to assign the URL of the GET request to the src attribute.
Upvotes: 0