简体   繁体   中英

Javascript send metadata with zip file in xhttp POST request

I need to upload zip-files with metadata like a title and certain number.

Either I'm sending the zip file directly with:

function generalPostRequest(content, url, cb) {    
    var xhttp = new XMLHttpRequest();
    xhttp.open("POST", url, true);
    xhttp.withCredentials = true;
    xhttp.setRequestHeader("Authorization", "Basic " + btoa("NAME:PASS"));

    //DIFF
    xhttp.setRequestHeader("Content-Type", "application/zip");
    //DIFF

    xhttp.onreadystatechange = function () {
        if (xhttp.readyState === 4 && xhttp.status === 200) {
            if (cb) {
                cb(JSON.parse(xhttp.response));
            }
        }
    };
    xhttp.send(content);//DIFF
}

But then I don't know how to add metadata. The other way would be:

function generalPostRequest(content, url, cb) {
    var xhttp = new XMLHttpRequest();
    xhttp.open("POST", url, true);
    xhttp.withCredentials = true;
    xhttp.setRequestHeader("Authorization", "Basic " + btoa("NAME:PASS"));

    //DIFF
    xhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    var params = JSON.stringify(content);
    //DIFF

    xhttp.onreadystatechange = function () {
        if (xhttp.readyState === 4 && xhttp.status === 200) {
            if (cb) {
                cb(JSON.parse(xhttp.response));
            }
        }
    };
    xhttp.send(params);//DIFF
}

But if I add the zip into an array, the JSON.stringify function removes the zip file. I probably have to convert it into a byte array.

How do I add metadata to solution 1 or how do I convert a zip to a byte array in solution 2?

I haven't actually tested this, and since I don't know exactly what kind of value content holds, it is difficult to construct a proper test case anyway .

You are trying to send a JSON file and a Zip file in one request. The way to do that is with a multipart request.

XMLHttpRequest can construct a multipart request from a FormData object.

You just need to create one and feed it the right data.

var zip_data = get_zip_data();
var json_data = get_json_data();

var zip_file = new File(zip_data, "example.zip", { type: "application/zip" });
var json_file = new File(json_data, "example.json", { type: "application/json" });

var form_data = new FormData();
form_data.append("zip", zip_file, "example.zip");
form_data.append("json", json_file, "example.json");

var xhttp = new XMLHttpRequest();
xhttp.open("POST", url);
xhttp.withCredentials = true;
xhttp.setRequestHeader("Authorization", "Basic " + btoa("NAME:PASS"));
xhttp.addEventListener("load", load_handler);
xhttp.send(form_data);

function load_handler() {
    if (cb) {
        cb(JSON.parse(xhttp.response));
    }
}

Note that you must not set the Content-Type header. XHR will generate it from the FormData object automatically (and it has to do this as it needs to generate boundry markers between the files).

This should result in the two files being sent to the server as if you had picked them with <input type="file"> in a regular form. Write the server side code accordingly (eg use $_FILES if you are using PHP or something like multer if you are using Node.js).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM