如何将多部分表单数据从 js 发送到 Rails?
How to send multipart form data from js to Rails?
这就是我测试控制器的方式,只是为了展示请求结构的工作原理:
post(
:create,
params: {
play_session: {
comment: "COMMENT",
time_in_minutes: 10,
video: fixture_file_upload("video.webm")
}
}
)
我正在尝试通过 JS 到达此端点:
async function uploadFile(blob) {
let play_session = { comment: "SUPER GOOD COMMENT", time_in_minutes: 23, video: blob };
let formData = new FormData();
formData.append("play_session", play_session);
try {
let response =
await fetch(
"http://localhost:3000/front/play_sessions",
{
method: "POST",
body: formData
}
);
console.log("HTTP response:", response);
} catch(e) {
console.log("Huston we have problem...:", e);
}
}
但我在 Rails 控制台中收到此错误:
Started POST "/front/play_sessions" for ::1 at 2021-09-24 22:00:30 +0200
Processing by Front::PlaySessionsController#create as */*
Parameters: {"play_session"=>"[object Object]"}
Completed 500 Internal Server Error in 3ms (Allocations: 1717)
NoMethodError (undefined method `permit' for "[object Object]":String):
我试过像这样将 headers 添加到 fetch
调用中:
await fetch(
"http://localhost:3000/front/play_sessions",
{
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "multipart/form-data"
},
body: formData
}
);
然后我在 Rails 控制台出现这个错误:
Started POST "/front/play_sessions" for ::1 at 2021-09-24 22:02:59 +0200
Processing by Front::PlaySessionsController#create as JSON
Parameters: {"------WebKitFormBoundaryESNX0mluVZ8VIiry\r\nContent-Disposition: form-data; name"=>"\"play_session\"\r\n\r\n[object Object]\r\n------WebKitFormBoundaryESNX0mluVZ8VIiry--\r\n"}
Completed 400 Bad Request in 1ms (Allocations: 520)
ActionController::ParameterMissing (param is missing or the value is empty: play_session
Did you mean? ------WebKitFormBoundaryESNX0mluVZ8VIiry
Content-Disposition: form-data; name
action
controller):
FormData 的 append 接受 name
、value
对,其中 value
可以是字符串或 Blob。
value
The field's value. This can be a USVString or Blob (including subclasses such as File). If none of these are specified the value is converted to a string.
在这里,formData.append("play_session", play_session)
您分配一个对象。
因为Rails在params中创建Hashes & Arrays很聪明,你需要一个一个追加来自play_session
的参数:
let formData = new FormData();
formData.append('play_session[comment]', 'SUPER GOOD COMMENT')
formData.append('play_session[time_in_minutes]', 23)
formData.append('play_session[video]', blob)
对于嵌套属性你应该做的:
formData.append('play_session[user_attributes][name]', 'Jack');
对于数组:
formData.append('play_session[user_ids][]', "1");
formData.append('play_session[user_ids][]', "2");
这就是我测试控制器的方式,只是为了展示请求结构的工作原理:
post(
:create,
params: {
play_session: {
comment: "COMMENT",
time_in_minutes: 10,
video: fixture_file_upload("video.webm")
}
}
)
我正在尝试通过 JS 到达此端点:
async function uploadFile(blob) {
let play_session = { comment: "SUPER GOOD COMMENT", time_in_minutes: 23, video: blob };
let formData = new FormData();
formData.append("play_session", play_session);
try {
let response =
await fetch(
"http://localhost:3000/front/play_sessions",
{
method: "POST",
body: formData
}
);
console.log("HTTP response:", response);
} catch(e) {
console.log("Huston we have problem...:", e);
}
}
但我在 Rails 控制台中收到此错误:
Started POST "/front/play_sessions" for ::1 at 2021-09-24 22:00:30 +0200
Processing by Front::PlaySessionsController#create as */*
Parameters: {"play_session"=>"[object Object]"}
Completed 500 Internal Server Error in 3ms (Allocations: 1717)
NoMethodError (undefined method `permit' for "[object Object]":String):
我试过像这样将 headers 添加到 fetch
调用中:
await fetch(
"http://localhost:3000/front/play_sessions",
{
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "multipart/form-data"
},
body: formData
}
);
然后我在 Rails 控制台出现这个错误:
Started POST "/front/play_sessions" for ::1 at 2021-09-24 22:02:59 +0200
Processing by Front::PlaySessionsController#create as JSON
Parameters: {"------WebKitFormBoundaryESNX0mluVZ8VIiry\r\nContent-Disposition: form-data; name"=>"\"play_session\"\r\n\r\n[object Object]\r\n------WebKitFormBoundaryESNX0mluVZ8VIiry--\r\n"}
Completed 400 Bad Request in 1ms (Allocations: 520)
ActionController::ParameterMissing (param is missing or the value is empty: play_session
Did you mean? ------WebKitFormBoundaryESNX0mluVZ8VIiry
Content-Disposition: form-data; name
action
controller):
FormData 的 append 接受 name
、value
对,其中 value
可以是字符串或 Blob。
value
The field's value. This can be a USVString or Blob (including subclasses such as File). If none of these are specified the value is converted to a string.
在这里,formData.append("play_session", play_session)
您分配一个对象。
因为Rails在params中创建Hashes & Arrays很聪明,你需要一个一个追加来自play_session
的参数:
let formData = new FormData();
formData.append('play_session[comment]', 'SUPER GOOD COMMENT')
formData.append('play_session[time_in_minutes]', 23)
formData.append('play_session[video]', blob)
对于嵌套属性你应该做的:
formData.append('play_session[user_attributes][name]', 'Jack');
对于数组:
formData.append('play_session[user_ids][]', "1");
formData.append('play_session[user_ids][]', "2");