Upload file as JSON to Python webserver

微笑、不失礼 提交于 2019-12-25 04:14:55

问题


I want to upload a file as JSON from the client to a Python webserver (Tornado) and save it on the server. This is my simplified setup:

Client HTML:

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

Client 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. All uploaded files are empty (blank pages in a PDF, file type of JPG is 'not supported', Word file cannot be opened) and are nearly twice as big as the original file. How can I fix this?
  2. Is there a way to improve this setup?

回答1:


You are trying to upload binary files (word, jpg), serialised as JSON, and store them on the server.

To handle binary data in JSON, encode the binary data as base64 first, then call JSON.stringify.

Like this (untested):

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));
}

On the server side, you need to deserialise from JSON, decode the base64 and the open a file in binary mode to ensure that what you are writing to disk is the uploaded binary data. Opening the file in text mode requires that the data be encoded before writing to disk, and this encoding step will corrupt binary data.

Something like this ought to work:

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)


来源:https://stackoverflow.com/questions/52117156/upload-file-as-json-to-python-webserver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!