vibe.d 的多部分表单数据
Multipart form data with vibe.d
我正在尝试提交包含带有 vibe.d
图片的多部分表单
我的代码如下所示:
auto f = File("image.jpg");
auto data = new char[f.size];
f.rawRead(data);
string boundary = randomUUID.toString.toUpper();
string h = "--Boundary-" ~ boundary ~ "\r\n";
h ~= `Content-Disposition: form-data; name="type"` ~ "\r\n\r\n";
h ~= "photo\r\n";
h ~= "--Boundary-" ~ boundary ~ "\r\n";
h ~= `Content-Disposition: form-data; name="photo"; filename="558704D0-2855-4689-996C-F556BE4A3872.jpg"` ~ "\r\n";
h ~= "Content-Type: image/jpeg\r\n\r\n";
h ~= data ~ "\r\n";
h ~= "--Boundary-" ~ boundary ~ "\r\n";
h ~= `Content-Disposition: form-data; name="photo_ids"` ~ "\r\n\r\n";
h ~= `["55227F15-36D2-4A04-A4D9-FB23C00627D1"]` ~ "\r\n";
h ~= "--Boundary-" ~ boundary ~ "\r\n";
auto response = requestHTTP("https://httpbin.org/anything", (scope req) {
req.method = HTTPMethod.POST;
req.headers["content-type"] = "multipart/form-data; boundary=Boundary-" ~ boundary;
req.headers["content-length"] = to!string(h.length);
req.bodyWriter.write(h);
}).bodyReader.readAllUTF8();
logInfo(response);
但是 httpbin 告诉我我没有发布任何内容:
[main(----) INF] {
[main(----) INF] "args": {},
[main(----) INF] "data": "",
[main(----) INF] "files": {},
[main(----) INF] "form": {},
[main(----) INF] "headers": {
[main(----) INF] "Accept-Encoding": "gzip, deflate",
[main(----) INF] "Content-Length": "58038",
[main(----) INF] "Content-Type": "multipart/form-data; boundary=Boundary-76CCC942-83EB-4339-BB6B-2C7D5BF027B6",
[main(----) INF] "Host": "httpbin.org",
[main(----) INF] "User-Agent": "vibe.d/1.7.0 (HTTPClient, +http://vibed.org/)"
[main(----) INF] },
[main(----) INF] "json": null,
[main(----) INF] "method": "POST",
[main(----) INF] "origin": "",
[main(----) INF] "url": "https://httpbin.org/anything"
[main(----) INF] }
我不知道我做错了什么。非常感谢任何帮助
您的多部分数据格式不正确。对于 last 边界,您必须附加一个“--”字符串以指示结束。所以而不是 last
h ~= "--Boundary-" ~ boundary ~ "\r\n";
需要
h ~= "--Boundary-" ~ boundary ~ "--\r\n";`
然后就可以了。
见https://www.freesoft.org/CIE/RFC/1521/16.htm
最终这应该在 vibe.d 中作为 API 得到支持,并且有 2 个开放的 PR,但现在你必须像以前一样解决它。
现在使用 Vibe.d 的当前版本要简单得多。
确保在表单的 enctype 中注明 'multipart/form-data':
form.form-grid(method="post", action="new_employee", enctype="multipart/form-data")
然后该表单中的字段应包含类型为 'file' 的输入字段,如下所示:
input(type="file", name="picture")
在你的web框架class的postNewEmployee()方法中,通过request.files获取文件:
auto pic = "picture" in request.files;
这是一个传递给 Employee 结构的 postNewEmployee() 方法示例:
void postNewEmployee(string _authUser, Employee e)
{
import std.file;
import std.path;
import std.algorithm;
string photopath = "No photo submitted";
auto pic = "picture" in request.files;
if(pic !is null)
{
string ext = extension(pic.filename.name);
string[] exts = [".jpg", ".jpeg", ".png", ".gif"];
if(canFind(exts, ext))
{
photopath = "uploads/photos/" ~ e.fname ~ "_" ~ e.lname ~ ext;
string dir = "./public/uploads/photos/";
mkdirRecurse(dir);
string fullpath = dir ~ e.fname ~ "_" ~ e.lname ~ ext;
try moveFile(pic.tempPath, NativePath(fullpath));
catch (Exception ex) copyFile(pic.tempPath, NativePath(fullpath));
}
}
e.photo = photopath;
if(e.phone.length == 0) e.phone = "(123) 456 7890";
if(e.paygd.length == 0) e.paygd = "none yet";
if(e.postcode.length == 0) e.postcode = "A1A 1A1";
e.pword = createDigestPassword(realm, e.email, e.pword);
empModel.addEmployee(e);
redirect("list_employees");
}
当我再次尝试学习Vibe.d时,我再次意识到教程的匮乏,所以我自己写了一个教程,作为一个学习者,一切都是新鲜的:
https://github.com/reyvaleza/vibed
希望你觉得这很有用。
我正在尝试提交包含带有 vibe.d
图片的多部分表单我的代码如下所示:
auto f = File("image.jpg");
auto data = new char[f.size];
f.rawRead(data);
string boundary = randomUUID.toString.toUpper();
string h = "--Boundary-" ~ boundary ~ "\r\n";
h ~= `Content-Disposition: form-data; name="type"` ~ "\r\n\r\n";
h ~= "photo\r\n";
h ~= "--Boundary-" ~ boundary ~ "\r\n";
h ~= `Content-Disposition: form-data; name="photo"; filename="558704D0-2855-4689-996C-F556BE4A3872.jpg"` ~ "\r\n";
h ~= "Content-Type: image/jpeg\r\n\r\n";
h ~= data ~ "\r\n";
h ~= "--Boundary-" ~ boundary ~ "\r\n";
h ~= `Content-Disposition: form-data; name="photo_ids"` ~ "\r\n\r\n";
h ~= `["55227F15-36D2-4A04-A4D9-FB23C00627D1"]` ~ "\r\n";
h ~= "--Boundary-" ~ boundary ~ "\r\n";
auto response = requestHTTP("https://httpbin.org/anything", (scope req) {
req.method = HTTPMethod.POST;
req.headers["content-type"] = "multipart/form-data; boundary=Boundary-" ~ boundary;
req.headers["content-length"] = to!string(h.length);
req.bodyWriter.write(h);
}).bodyReader.readAllUTF8();
logInfo(response);
但是 httpbin 告诉我我没有发布任何内容:
[main(----) INF] {
[main(----) INF] "args": {},
[main(----) INF] "data": "",
[main(----) INF] "files": {},
[main(----) INF] "form": {},
[main(----) INF] "headers": {
[main(----) INF] "Accept-Encoding": "gzip, deflate",
[main(----) INF] "Content-Length": "58038",
[main(----) INF] "Content-Type": "multipart/form-data; boundary=Boundary-76CCC942-83EB-4339-BB6B-2C7D5BF027B6",
[main(----) INF] "Host": "httpbin.org",
[main(----) INF] "User-Agent": "vibe.d/1.7.0 (HTTPClient, +http://vibed.org/)"
[main(----) INF] },
[main(----) INF] "json": null,
[main(----) INF] "method": "POST",
[main(----) INF] "origin": "",
[main(----) INF] "url": "https://httpbin.org/anything"
[main(----) INF] }
我不知道我做错了什么。非常感谢任何帮助
您的多部分数据格式不正确。对于 last 边界,您必须附加一个“--”字符串以指示结束。所以而不是 last
h ~= "--Boundary-" ~ boundary ~ "\r\n";
需要
h ~= "--Boundary-" ~ boundary ~ "--\r\n";`
然后就可以了。
见https://www.freesoft.org/CIE/RFC/1521/16.htm
最终这应该在 vibe.d 中作为 API 得到支持,并且有 2 个开放的 PR,但现在你必须像以前一样解决它。
现在使用 Vibe.d 的当前版本要简单得多。
确保在表单的 enctype 中注明 'multipart/form-data':
form.form-grid(method="post", action="new_employee", enctype="multipart/form-data")
然后该表单中的字段应包含类型为 'file' 的输入字段,如下所示:
input(type="file", name="picture")
在你的web框架class的postNewEmployee()方法中,通过request.files获取文件:
auto pic = "picture" in request.files;
这是一个传递给 Employee 结构的 postNewEmployee() 方法示例:
void postNewEmployee(string _authUser, Employee e)
{
import std.file;
import std.path;
import std.algorithm;
string photopath = "No photo submitted";
auto pic = "picture" in request.files;
if(pic !is null)
{
string ext = extension(pic.filename.name);
string[] exts = [".jpg", ".jpeg", ".png", ".gif"];
if(canFind(exts, ext))
{
photopath = "uploads/photos/" ~ e.fname ~ "_" ~ e.lname ~ ext;
string dir = "./public/uploads/photos/";
mkdirRecurse(dir);
string fullpath = dir ~ e.fname ~ "_" ~ e.lname ~ ext;
try moveFile(pic.tempPath, NativePath(fullpath));
catch (Exception ex) copyFile(pic.tempPath, NativePath(fullpath));
}
}
e.photo = photopath;
if(e.phone.length == 0) e.phone = "(123) 456 7890";
if(e.paygd.length == 0) e.paygd = "none yet";
if(e.postcode.length == 0) e.postcode = "A1A 1A1";
e.pword = createDigestPassword(realm, e.email, e.pword);
empModel.addEmployee(e);
redirect("list_employees");
}
当我再次尝试学习Vibe.d时,我再次意识到教程的匮乏,所以我自己写了一个教程,作为一个学习者,一切都是新鲜的:
https://github.com/reyvaleza/vibed
希望你觉得这很有用。