AJAX에서 중첩된 FormData 전송
Ajax와 FormData를 사용하여 데이터를 보내야 합니다. 파일과 기타 파라미터를 보내고 싶기 때문입니다.제가 보통 데이터를 보내는 방법은 다음과 같습니다.
$.ajax({
type: 'POST',
url: 'some_url',
dataType: 'json',
processData:false,
contentType:false,
data:{
Lvl_1-1: 'something',
Lvl_1-2: 'something',
Lvl_1-3: {
Lvl_1-3-1: "something",
Lvl_1-3-2: "something",
Lvl_1-3-3: "something",
},
},
...
});
FormData()를 사용하지 않으면 문제가 없지만 FormData()를 사용하면 Lvl1의 데이터만 정상이지만 중첩된 항목은 다음과 같이 문자열로 표시됩니다.
<b>array</b> <i>(size=3)</i>
'Lvl1-1' <font color='#888a85'>=></font> <small>string</small>
<font color='#cc0000'>'Something'</font>
<i>(length=23)</i>
'Lvl1-2' <font color='#888a85'>=></font> <small>string</small>
<font color='#cc0000'>''Something''</font> <i>(length=3)</i>
'Lvl1-3' <font color='#888a85'>=></font> <small>string</small>
<font color='#cc0000'>'[object Object]'</font> <i>(length=17)</i>
() 대신 내부의 데이터를 [object Object]알겠습니다[object FormData]
Lvl1-3에서 문자열 대신 배열을 얻으려면 어떻게 해야 합니까?
참고: 파일이 최상위 수준(Lvl_1)이면 FormData()를 사용하여 문제없이 파일을 보낼 수 있습니다.첨부된 파일의 코드를 작성하지 않은 것은 그것이 문제가 아니라 중첩된 데이터이기 때문입니다.FormData()를 사용하기 때문에 파일을 언급한 것입니다.
URL 인코딩 양식 데이터에는 복잡한 데이터 구조를 표현하는 기본적인 방법이 없습니다.단순 키=값 쌍만 지원합니다.
?foo=1&bar=2
대부분의 양식 데이터 구문 분석 라이브러리는 동일한 이름의 키를 사용하여 데이터 배열을 허용합니다.
?foo=1&foo=2
PHP는 그 형식 위에 자체 구문을 볼트로 고정했습니다.
?foo[]=1&foo[]=2
연관 배열에서 명명된 키를 허용했습니다.
?foo[bar]=1&foo[baz]=2
및 중첩 배열:
?foo[bar][level2a]=1&foo[bar][level2b]=2
PHP의를 PHP로 때폼하기 위한 했습니다.data.
당신이 경우용을 사용하고 .FormData그러면 jQuery가 재처리하지 않습니다.
있는 의 그 않았습니다를 두 번째 입니다.append여기서 문자열이 필요합니다.
직접 PHP의 구문을 사용하여 키 이름을 생성해야 합니다.
form_data_instance.append("Lvl_1-3[Lvl_1-3-1]", "something");
form_data_instance.append("Lvl_1-3[Lvl_1-3-2]", "something");
form_data_instance.append("Lvl_1-3[Lvl_1-3-3]", "something");
저는 중첩된 매개 변수를 문자열화하고 다른 쪽에서 구문 분석합니다.
예를 들어, 제가 합격하고 싶다면:
{"sthing":
{"sthing":"sthing"},
{"picture":
{"legend":"great legend"},
{"file":"great_picture.jpg"}
}
}
그럼, 나는...
// On the client side
const nestedParams = {"sthing":
{"sthing":"sthing"},
{"picture":
{"legend":"great legend"}
}
};
const pictureFile = document.querySelector('input[type="file"]')[0];
const formDataInstance = new FormData;
formDataInstance.append("nested_params": JSON.stringify(nested_params);
formDataInstance.append("file": document.querySelector('input[type="file"]')[0]);
// On the server side
params["nested_params"] = JSON.parse(params["nested_params"]);
params["nested_params"]["sthing"]["picture"]["file"] = params["file"];
Quentin의 답변에 덧붙여, 저는 다음과 같은 PHP Laravel 코드를 가지고 있었습니다.
$tags = [];
foreach ($request->input('tags') as $tag) {
if (!is_array($tag)) {
$new_tag = Tag::generate($tag);
array_push($tags, $new_tag->id);
} else {
array_push($tags, $tag['id']);
}
}
배열로 해서 빈 로 배 시 하 작 값 볼 수 있 습 니 다 것 채 는 을 우 로 으 열 다 여 음 , ▁from 니 다 있 습 ▁you ▁it 수 ▁values ▁array ▁empty ▁with 볼 ▁see 빈 ▁an ▁i ▁fill ▁and ▁can ▁with ▁then ▁i ▁start열 배$request->input('tags')해당 요청 입력은 다차원 배열이므로 이 질문에 설명된 문제가 발생했습니다.FormData를 사용할 때만 나타납니다.multipart/form-data양식 인코딩 형식입니다.
저는 Quentin의 답변과 여기에 있는 클라이언트 측 JavaScript 코드로 이 문제를 해결할 수 있었습니다.
this.example.tags.forEach((tag, i) => {
if (Object.prototype.toString.call(tag) === '[object String]') {
payload.append(`tags[${i}]`, tag);
} else {
Object.keys(tag).forEach(field => payload.append(`tags[${i}][${field}]`, tag[field]));
}
});
이 코드는 먼저 FormData에 추가하려는 태그가 문자열인지 확인합니다.그렇다면 존재하지 않는 새 태그입니다.그런 다음 인덱스 번호로 추가합니다.태그가 이미 존재한다면, 나는 고객이 가지고 있던 모든 값을 보냅니다.의 경우,ID(행 에 대한 관계)만, " " " " " " " " " 와 같은 입니다. 그러나 다음과 같은 구문을 사용하는 데는 좋은 연습이 됩니다.arr[index][field].
쿠엔틴과 내 대답을 공부하면 패턴을 볼 수 있을 것입니다.저의 사례 또한 본질적으로 다소 사소하지 않은 점이 있으므로 제 의견으로 검토해 보면 좋을 것입니다.
완전히 이해하기 위해 페이로드는 다음과 같습니다.
'tags' =>
array (
0 =>
array (
'id' => '2',
'name' => 'React JS',
),
1 =>
array (
'id' => '5',
'name' => 'JSON Web Tokens',
),
2 => 'Sandwiches',
),
3개의 태그가 있는 것을 볼 수 있습니다.처음 두 개는 이미 존재합니다.세 번째 것은 내 데이터베이스에 존재하지 않기 때문에 객체가 아닌 문자열 값으로 들어옵니다.Laravel/PHP는 중첩된 개체 "기존 태그"를 좋아하지 않기 때문에 FormData(이미지가 있는 다중 부분 인코딩 유형)를 수정해야 했습니다.
다음은 전체 submitForm 함수입니다.
const payload = new FormData();
Object.keys(this.example).forEach(field => payload.append(field, this.example[field]));
this.example.tags.forEach((tag, i) => {
if (Object.prototype.toString.call(tag) === '[object String]') {
payload.append(`tags[${i}]`, tag);
} else {
Object.keys(tag).forEach(field => payload.append(`tags[${i}][${field}]`, tag[field]));
}
});
this.example.images.forEach(image => payload.append('images[]', image));
const response = await axios.post(route('admin.examples.create'), payload);
참조:JavaScript에서 변수가 문자열인지 확인합니다.
언급URL : https://stackoverflow.com/questions/28774746/sending-nested-formdata-on-ajax
'programing' 카테고리의 다른 글
| JavaScript 개체의 속성을 계산하려면 어떻게 해야 합니까? (0) | 2023.08.31 |
|---|---|
| Javascript Array Concat이 작동하지 않습니다. 왜죠? (0) | 2023.08.31 |
| Docker CMD를 여러 번 사용하여 여러 서비스를 실행할 수 없는 이유는 무엇입니까? (0) | 2023.08.31 |
| 동적 입력 배열에 대한 null 값 삽입 (0) | 2023.08.31 |
| VBA에서 이벤트 수신기를 프로그래밍 방식으로 생성 (0) | 2023.08.31 |