Загрузить файл в формате JSON на веб-сервер Python - PullRequest
0 голосов
/ 31 августа 2018

Я хочу загрузить файл в формате JSON с клиента на веб-сервер Python (Tornado) и сохранить его на сервере. Это моя упрощенная настройка:

Клиентский HTML:

<input type="file" id="myFile" onchange="fileChange" />

Клиент JS:

function fileChange(event) {
    const file = event.target.files[0];
    const fileReader = new FileReader();
    fileReader.onload = (e) => uploadFile(e.target.result, file.name);
    fileReader.readAsText(file);
}

function uploadFile(fileContent, fileName) {
    const data = {fileContent, fileName};
    axios.post('http://localhost:8080/api/uploadFile', JSON.srtingify(data));
}

Python Webserver:

class UploadFileHandler(tornado.web.RequestHandler):

    def post(self):
        requestBody = tornado.escape.json_decode(self.request.body)
        file = open(requestBody["fileName"], "w+")
        file.write(requestBody["fileContent"].encode("UTF-8"))
        file.close()
  1. Все загруженные файлы являются пустыми (пустые страницы в PDF, тип файла JPG «не поддерживается», файл Word не может быть открыт) и почти в два раза больше исходного файла. Как я могу это исправить?
  2. Есть ли способ улучшить эту настройку?

1 Ответ

0 голосов
/ 01 сентября 2018

Вы пытаетесь загрузить двоичные файлы (word, jpg), сериализованные как JSON, и сохранить их на сервере.

Чтобы обработать двоичные данные в JSON, сначала кодируют двоичные данные как base64 , а затем вызывают JSON.stringify.

Как это (не проверено):

function uploadFile(fileContent, fileName) {
    // Encode the binary data to as base64.
    const data = {
        fileContent: btoa(fileContent),
        fileName: fileName
    };
    axios.post('http://localhost:8080/api/uploadFile', JSON.stringify(data));
}

На стороне сервера вам необходимо десериализовать из JSON, декодировать base64 и открыть файл в двоичном режиме , чтобы убедиться, что вы записываете на диск загруженные двоичные данные. Открытие файла в текстовом режиме требует, чтобы данные были зашифрованы перед записью на диск, и этот шаг кодирования повредит двоичные данные.

Как-то так должно работать:

class UploadFileHandler(tornado.web.RequestHandler):

    def post(self):
        requestBody = tornado.escape.json_decode(self.request.body)
        # Decode binary content from base64
        binary_data = base64.b64decode(requestBody[fileContent])
        # Open file in binary mode
        with open(requestBody["fileName"], "wb") as f:
            f.write(binary_data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...