如何在 C++ 中使用 Emscripten 上传文件?

How do you upload a file using Emscripten in C++?

我正在尝试将文件上传到服务器。我已经成功地使用带有 GET 请求的 Emscripten 的 Fetch API 下载数据,但到目前为止 POST 请求没有成功。

这是我当前的实现:(文件正在按预期打开和读取,但服务器未接收到文件)

void uploadSucceeded(emscripten_fetch_t* fetch)
{
    printf("Successful upload of %llu bytes to %s.\n", fetch->numBytes, fetch->url);
    // The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
    emscripten_fetch_close(fetch); // Free data associated with the fetch.
}

void uploadFailed(emscripten_fetch_t* fetch)
{
    printf("Failed upload to %s - HTTP failure status code: %d.\n", fetch->url, fetch->status);
    emscripten_fetch_close(fetch); // Also free data on failure.
}

bool UploadFile(const std::string& url, const std::string& file_name)
{
    emscripten_fetch_attr_t attr;
    emscripten_fetch_attr_init(&attr);
    strcpy(attr.requestMethod, "POST");
    attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
    attr.onsuccess  = uploadSucceeded;
    attr.onerror    = uploadFailed;

    // Set headers:
    const char* headers[] = { "Content-Type", "application/x-www-form-urlencoded", 0 };
    attr.requestHeaders = headers;
    
    // Read file data:
    std::ifstream in_file(file_name.c_str(), std::ios::binary);
    //
    in_file.seekg(0, std::ios::end);
    int file_size = in_file.tellg();
    //
    in_file.seekg(0, std::ios::beg);
    std::stringstream buffer;
    buffer << in_file.rdbuf();
    //
    char *cstr = new char[buffer.str().length() + 1];
    strcpy(cstr, buffer.str().c_str());
    //
    attr.requestData = cstr;
    attr.requestDataSize = file_size;

    // Send HTTP request:
    emscripten_fetch(&attr, url.c_str());
    return true;
}

您需要确保请求 header 具有:

"Content-Type", "multipart/form-data; boundary=[custom-boundary]\r\n"

...其中 [custom-boundary] 是您选择的字符串。

然后在请求数据中,您从该自定义边界开始,然后是 "\r\n",然后是另一个 header,例如:

"Content-Disposition: form-data; name=\"myFile\" filename=\"G0000U00000R01.html\"\r\n"
"Content-Transfer-Encoding: binary\r\n"
"Content-Type: text/html\r\n\r\n"

...之后是文件内容,然后是 "\r\n",最后是与之前相同的自定义边界。