>웹 프론트엔드 >JS 튜토리얼 >자바스크립트 및 양식 양식 고급 학습

자바스크립트 및 양식 양식 고급 학습

伊谢尔伦
伊谢尔伦원래의
2016-11-21 13:55:441087검색

서문

이전 글에서는 폼을 이용하여 앞, 뒤 데이터의 상호작용에 대해 이야기한 적이 있는데, 폼에서 브라우저와 서버 간의 연결에 대해 몇 가지 설명한 것 같습니다. 형식을 마스터했지만 현실은 잔혹합니다. 최근 프로젝트에서 이전 기사에서 방금 클릭한 형식에 대한 많은 지식이 있음을 발견했습니다. 이 컨텐츠는 파일업로드 등 꽤 많은 곳에서 사용됩니다.

1. FormData

이전 글에서 폼을 정리하는 방법은 jquery의 serializeArray 함수를 사용하는 것이라고 언급했는데, 이 방법은 input[type="file"]에는 유효하지 않습니다. 파일의 내용을 양식에 통합할 수 없다고 합니다. 관련 문제는 jquery 공식 이슈(https://bugs.jquery.com/ticket/2656)를 참조하세요. 설명은 다음과 같습니다.

직렬화 메소드는 파일의 내용을 가져올 수 없으므로 파일 양식 필드를 직렬화해야 하는 이유를 이해할 수 없습니다. Ajax 파일 중 하나를 사용해야 합니다. 플러그인을 업로드하면 AJAX를 통해 콘텐츠를 얻을 수 있습니다.

 그럼 플러그인을 사용하지 않고도 제출된 양식을 얻을 수 있을까요? 당연하죠!

 1.1. FormData의 역할

 저희가 소개하고 싶은 FormData입니다. FormData의 MDN 설명에 따르면:

FormData 인터페이스는 필드와 값을 나타내는 키-값 쌍을 작성하는 간단한 방법을 제공하며 `XMLHttpRequest.send를 통해 쉽게 전달될 수 있습니다. ()`가 서버로 전송되었습니다. 양식의 인코딩 유형이 `multipart/form-data`로 설정된 것과 동일한 형식을 사용합니다.

`entries()` 대신 `for...of`를 사용하여 FormData 객체를 탐색할 수 있습니다. `for (var p of myFormData)`는 ` for (var p of myFormData.entries() )`


이 설명을 통해 최소한 두 가지 사항을 이해할 수 있었습니다.

FormData는 multipart/form을 처리하는 데 사용할 수 있습니다. -데이터 인코딩 유형 양식 일반적으로 input[type="file"];

FormData의 필드는...in을 통해 확인할 수 있습니다. (이 개체는 브라우저에서 console.log를 사용하여 인쇄할 수 없습니다.)


그러면 일부 어린이는 분명히 다음과 같이 묻습니다.

사용하지 않습니까? FormData를 사용하여 input[type="file"] 없이 양식을 제출할 수 있습니까?

FormData를 사용하여 input[type="file"] 없이 x-www-form-urlencoded 인코딩 유형으로 양식을 제출하는 경우 어떻게 되나요?

FormData를 사용하지 않는 경우 input[type="file"]로 양식을 제출할 수 없나요?


그런 다음 데모를 사용하여 이 두 가지 문제를 설명합니다.

네, 현재 인코딩 유형은 양식 제출 방법인 multipart/form-data입니다. 대략 다음과 같습니다.

이 인코딩 유형 형식이 다르다는 것을 알 수 있습니다. 서버 측에서 express4 이상을 사용하는 경우 이러한 유형의 요청을 처리하기 위해 추가 미들웨어를 설치해야 합니다. 그렇지 않으면 req.body, req.param 및 req.query에서 양식 데이터를 찾을 수 없습니다. 이에 대해서는 나중에 논의하겠습니다. 그렇다면 우리는 여전히 이 방법을 사용하여 간단한 양식을 제출하는 것을 옹호하지 않는 이유가 있습니다(대부분의 웹사이트가 이에 해당합니다).

우리가 제출한 양식이 단 몇 글자에 불과하다는 사실을 발견하셨을 것입니다. 이러한 경계로 인해 양식 데이터가 더 커집니다. 즉, 가장 효율적인 바이너리 인코딩이라도 양식 데이터를 MIME 헤더에 직접 쓰는 데 걸리는 시간보다 더 오래 걸립니다.

팁: 그러나 x-www-form-urlencoded는 영숫자가 아닌 문자를 처리하는 데 어려움을 겪습니다. 왜냐하면 브라우저가 영숫자가 아닌 문자를 %HH로 변환하기 때문입니다. 즉, 영숫자가 아닌 모든 문자는 %HH로 변환됩니다. 영숫자 문자는 3바이트로 대체됩니다. 이는 양식이 매우 길면 매우 불리하므로 multipart/form-data가 나타납니다.

두 번째 질문에 대답하려면 서버(express4)에서 req.body를 볼 수 있습니다.

{ '------ -WebKitFormBoundary5Kj2oSfHZKrZjYjsrnContent -처리: 양식-데이터; 이름': '"사용자"rnrnddrn------WebKitFormBoundary5Kj2oSfHZKrZjYjsrnContent-처리: 양식-데이터; 이름="email"rnrndddrn------WebKitFormBoundary5Kj2oSfHZKrZjYjs- -rn' }

코드 복사
보세요, 서버에 어떻게 파싱을 요청하나요? ? ? 이것은 나 자신에게 문제를 일으키고 있습니다.

FormData의 유령을 사용하지 않는 경우 순수 AJAX를 사용하여 제출할 수도 있습니다. 자세한 내용은 https://developer.mozilla.org/en-US/를 참조하세요. docs/Web/API/XMLHttpRequest/ XMLHttpRequest 사용#양식 제출 및 파일 업로드

 1.2 결론

요약하면, input[type="file"]을 포함하거나 여러 개를 포함하는 양식을 사용할 때 영숫자가 아닌 문자 양식을 제출하려면 FormData를 사용해야 하며 인코딩 유형은 multipart/form-data여야 합니다. 그러면 대략적으로 사용되는 예는 다음과 같습니다.

<!DOCTYPE html>  
<html>  
<head>  
    <meta charset="UTF-8">
    <title>testing form group</title>
    <script type="text/JavaScript" src="http://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
    <script type="text/JavaScript">
    function onSubmit(){
        var myForm = document.getElementById(&#39;form&#39;);
        var formData = new FormData(myForm);
        for (var p of formData){
            console.log(p);
        }
        $.ajax({
            type: &#39;POST&#39;,
            url: &#39;/get&#39;,
            data: formData,
            dataType: &#39;json&#39;,
            processData: false,
            contentType: false,
            success: function(data){console.log(data)},
            error: function(jqXHR){console.log(jqXHR)},
        })
    }
    </script>
</head>  
<body>  
    <form action="" method="post" name=&#39;info&#39; id=&#39;form&#39;>
        <input type="text" name="user" />
        <input type="text" name="email" />
        <input type="file" name="file" />
        <input type="file" name="file1" />
    </form>
    <button type="button" name=&#39;submit&#39; onclick="onSubmit()">提交</button>
</body>  
</html>

참고
$.ajax는 jquery가 데이터를 추가로 처리하지 못하도록 processData: false 및 contentType: false로 구성됩니다.

processData( 기본값: true)

유형: 부울

기본적으로 data 옵션을 통해 전달된 데이터가 객체인 경우(기술적으로 말하면 문자열이 아닌 한) 처리되어 기본 콘텐츠 유형 "application/x-www-form-urlencoded"와 일치하도록 쿼리 문자열로 변환됩니다. 변환하고 싶지 않은 DOM 트리 정보나 기타 정보를 보내려면 false로 설정하세요.

1.3, FormData API
FormData.append(): 기존 키에 새 값을 추가하거나 새 키를 추가합니다.

FormData.delete(): 키-값 쌍 삭제

FormData.entries(): 개체

FormData에서 키-값 쌍을 순회할 수 있도록 반복자를 반환합니다. (): 주어진 키의 첫 번째 값을 반환

FormData.getAll(): 주어진 키의 모든 값의 배열을 반환

FormData.has(): FormData 객체는 지정된 키-값 쌍을 사용합니다.

FormData.keys(): 모든 키-값 쌍의 키 반복을 허용하는 반복자를 반환합니다.

FormData.set(): 수정합니다. 기존 키 또는 새 키-값 쌍 추가

FormData.values(): 모든 키-값 쌍의 값을 순회할 수 있도록 반복자를 반환합니다


2. input[type="file"]

이러한 유형의 입력에 대해 언급해야 할 몇 가지 사항이 있습니다. 그렇지 않으면 다음에 잊어버릴 것입니다:

여러 속성 사용은 한 번에 여러 파일을 선택할 수 있으며, 수락 속성을 사용하여 해당 MIME 유형을 실행합니다.

$(element).files는 업로드된 파일의 이름과 업로드된 파일 수(.name 및 길이)를 가져올 수 있습니다.


파일을 업로드할 때 파일 이름이나 접미사를 확인해야 하는 경우가 있는데 이때 xxx - 형식을 확인하면 정규식이 유용합니다. vx.x.{json|yaml}(예: bower-v0.1.json) 파일에서 사용되는 정규식은 다음과 같습니다.

var reg = /^\w+\-v\d+\.{1}\d+\.(json|yaml)$/i;  
/*Check if the user has not selected uploaded file*/
    if ($(Element).val() === &#39;&#39;){
      finalRes.delete(&#39;file&#39;);
    } else {
      var fileCount = $(Element)[0].files.length;
      for (var i = 0; i < fileCount; i++) {
        if (reg.test($(Element)[0].files[i].name )){
          console.log(&#39;match&#39;);
        }else{
          alert(&#39;上传的文件名格式不正确&#39;);
          return;
        }
      }
    }

그런 다음 접미사를 제거하면 바꾸기를 사용할 수 있습니다. (/.(json|yaml)$/, '') 접미사를 제거합니다. 4. 양식을 지우는 좋은 기능은 다음과 같습니다.

function clearAllFields(){
    $(&#39;:input&#39;,&#39;#project-info&#39;)
    .not(&#39;:button, :submit, :reset, :hidden&#39;)
    .val(&#39;&#39;)
    .removeAttr(&#39;checked&#39;)
    .removeAttr(&#39;selected&#39;);
  }


$(element)는 업로드한 파일의 입력 태그를 나타냅니다.

finalRes는 새 FormData 이후의 양식 값입니다.

3. Express 서버 측 처리

Express4.x 이후 이동 미들웨어가 많기 때문에 multipart/form-data 인코딩 유형이 있는 양식을 처리하려면 직접 설치해야 합니다. 그러한 패키지가 많이 있으며 저는 다자간 미들웨어를 사용하기로 결정했습니다. 구체적인 사용 방법은 공식 홈페이지(https://github.com/expressjs/node-multiparty)를 참고하세요.

이 미들웨어를 사용하는 방법에는 두 가지가 있습니다.

이벤트 청취 양식 사용

콜백 양식 사용


프로젝트에서는 콜백 형식을 사용합니다.

router.post(&#39;/get&#39;, function(req, res, next) {  
  var form = new multiparty.Form();
  form.parse(req, function(err, fields, files) {
    if (fields === undefined || files === undefined){
      console.log(&#39;client send empty data  in posting new project&#39;);
      return res.status(200).json({err:"请求数据为空,请重新提交", status:&#39;failure&#39;});
    }
    console.log(fields, files);
    console.log(&#39;Upload completed!&#39;);
  });
});


파일의 필드와 필드는 양식에 제공한 이름에 따라 구성됩니다. 첫 번째 섹션의 end 코드를 입력하면 이때 결과는 다음과 같습니다.

{ user: [ &#39;test&#39; ], email: [ &#39;test1&#39; ] } 
{ file: 
   [ { fieldName: &#39;file&#39;,
       originalFilename: &#39;test.html&#39;,
       path: &#39;/home/private/test/QForTTWBipWSPSTpKsUGlRHE.html&#39;,
       headers: [Object],
       size: 876 } ],
  file1: 
   [ { fieldName: &#39;file1&#39;,
       originalFilename: &#39;test1.html&#39;,
       path: &#39;/home/private/test/aT5T2B_pkkxEVv5OUzjjCxIB.html&#39;,
       headers: [Object],
       size: 558 } ] }

이때 공식 홈페이지 설명에 따르면 기본 파일이 기본 폴더에 업로드되어 있습니다. 초기화 중에 uploadDir이 구성되지 않은 경우 시스템의 os.tmpdir()에 업로드됩니다.
이벤트 유형 구현도 유사하며, 공식 홈페이지에서 제공되는 데모를 참고하시면 됩니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.