HTML 형식으로 PUT 메소드 사용


175

HTML 폼에서 PUT 메서드를 사용하여 폼에서 서버로 데이터를 보낼 수 있습니까?

답변:



194

HTML 표준 에 따르면 할 수 없습니다 . 방법 특성에 유효한 값은 다음 getpost는 GET 및 HTTP POST의 방법에 대응. <form method="put">는 유효하지 않은 HTML이며로 처리됩니다 ( <form>예 : GET 요청 보내기).

대신 많은 프레임 워크가 단순히 POST 매개 변수를 사용하여 HTTP 메소드를 터널링합니다.

<form method="post" ...>
  <input type="hidden" name="_method" value="put" />
...

물론 이것은 서버 측 언 래핑이 필요합니다.


3
최종 표준이 아닌 초안을 연결했습니다. 다만 안정적인 HTML 버전은이를 제공하지 않습니다.
hakre

13
@hakre HTML5는 사실상의 표준이며, 시간이 지남에 따라 발전 할 것입니다. W3C가 "초안"이라고 부르는 것은> 99 % 이상의 브라우저 공급 업체의 의견을 바탕으로 3 년 이상 개발 된 문서이며 이미 구현되어 있습니다 (적어도 비 이동적인 섹션과 관련하여). 그들 모두는 영원히. 그러나 nitpickers 의 경우 HTML 4.01 (W3C 용어의 기술 요청) 과 동등한 정의 가 있습니다.
phihag

기분 나쁘게 느끼지 마십시오. 나는 이미 메모 한 것이고 다른 HTML 버전은 그것을 제공하지 않는다고 말했습니다 (XHTML 2를 약간 제외하지만 현재는 쓸모없는 초안입니다).
hakre

1
@hakre Rest는 내가 전혀 기분 나쁘지 않다고 확신했다. nitpicker를 언급하면서, XHTML은 기술적으로 HTML이 아니라고 언급해야합니다. 비록 하나 또는 두 개의 유사점을 찾을 수도 있지만;)
phihag

44

HTML 양식에서 "Put"메소드를 사용하여 HTML 양식에서 서버로 데이터를 보낼 수 있습니까?

예, 가능하지만 PUT이 아니라 GET 요청이 발생합니다. 태그 method속성에 유효하지 않은 값을 <form>사용하면 브라우저가 기본값을 사용합니다 get.

HTML 양식 (최대 HTML 버전 4 (, 5 초안) 및 XHTML 1)은 HTTP 요청 방법으로 GET 및 POST 만 지원합니다. 이에 대한 해결 방법은 서버에서 읽은 요청에 따라 숨겨진 양식 필드를 사용하여 POST를 통해 다른 방법을 터널링하고 그에 따라 요청을 전달하는 것입니다. XHTML 2.0 은 폼에 대해 GET, POST, PUT 및 DELETE를 지원할 계획이지만 PUT을 지원하지 않는 HTML5의 XHTML5 로 이동 합니다. [업데이트]

대안으로 양식을 제공 할 수 있지만 양식을 제출하는 대신 JavaScript와 함께 PUT 메소드를 사용하여 XMLHttpRequest를 작성하고 실행하십시오.



양식 요청은 사용자를 지정된 자원으로 리디렉션하므로 AJAX 요청은 양식 요청을 완전히 대체 할 수 없습니다. 예를 들어, 현재 브라우저에 경로 페이지를 표시 할 방법이 없습니다 PUT /resource.
JacopoStanchi

이렇게하는 것은 나쁜 생각입니다. 프레임 워크는 PUT의 양식 매개 변수를 무시할 수 있습니다. Java의 HTTPServlet이 보인다. HttpRequest.getParameterMap()양식 매개 변수를 반환하지 않는 버그가있었습니다 .
DaBlick

@DaBlick : 그러나 XMLHttpRequests에는 적합하지 않습니까? 그렇다면 가져 오기 API를 사용하는 것이 더 표준화되어야합니다.
hakre

27

_method 숨겨진 필드 해결 방법

다음과 같은 간단한 기술이 몇 가지 웹 프레임 워크에서 사용됩니다.

  • _methodGET 또는 POST가 아닌 양식에 숨겨진 매개 변수를 추가하십시오 .

    <input type="hidden" name="_method" value="PUT">

    이것은 HTML 생성 도우미 메소드를 통해 프레임 워크에서 자동으로 수행 될 수 있습니다.

  • 실제 양식 메소드를 POST ( <form method="post") 로 수정하십시오.

  • _method서버에서 처리 하고 실제 POST 대신 해당 메소드가 전송 된 것처럼 정확하게 수행

당신은 이것을 달성 할 수 있습니다 :

  • 울타리: form_tag
  • 라 라벨 : @method("PATCH")

순수 HTML에서 불가능한 이유 / 이력 : /software/114156/why-there-are-no-put-and-delete-methods-in-html-forms


Laravel (PHP)을 사용하여 동일한 기능을 갖는다@method("PATCH")
산티아고 arizti

합리적인 해결 방법처럼 보이지만 디버깅이 어렵 기 때문에 여전히 불행합니다. 예를 들어, 서버 로그를 살펴 보거나 네트워크 분석을 수행하여 일부 사항을 확인해야하는 경우 HTTP 헤더에 사용되는 HTTP 메소드가 여전히 POST실제 필요하지 않기 때문에 올바른 출력이 표시되지 않습니다 .
code_dredd

8

불행히도 최신 브라우저는 HTTP PUT 요청에 대한 기본 지원을 제공하지 않습니다. 이 제한 사항을 해결하려면 HTML 양식의 메소드 속성이 "게시"인지 확인한 후 다음과 같이 메소드 대체 매개 변수를 HTML 양식에 추가하십시오.

<input type="hidden" name="_METHOD" value="PUT"/>

요청을 테스트하기 위해 Google 크롬 확장 프로그램 인 "Postman"을 사용할 수 있습니다.


1
삭제 및 패치 등을 포함한 모든 방법에서 작동해야합니다.
Tofeeq

1

PUT 및 DELETE 방법을 설정하려면 다음과 같이 수행하십시오.

<form
  method="PUT"
  action="domain/route/param?query=value"
>
  <input type="hidden" name="delete_id" value="1" />
  <input type="hidden" name="put_id" value="1" />
  <input type="text" name="put_name" value="content_or_not" />
  <div>
    <button name="update_data">Save changes</button>
    <button name="remove_data">Remove</button>
  </div>
</form>
<hr>
<form
  method="DELETE"
  action="domain/route/param?query=value"
>
  <input type="hidden" name="delete_id" value="1" />
  <input type="text" name="delete_name" value="content_or_not" />
  <button name="delete_data">Remove item</button>
</form>

그런 다음 JS는 원하는 방법을 수행합니다.

<script>
   var putMethod = ( event ) => {
     // Prevent redirection of Form Click
     event.preventDefault();
     var target = event.target;
     while ( target.tagName != "FORM" ) {
       target = target.parentElement;
     } // While the target is not te FORM tag, it looks for the parent element
     // The action attribute provides the request URL
     var url = target.getAttribute( "action" );

     // Collect Form Data by prefix "put_" on name attribute
     var bodyForm = target.querySelectorAll( "[name^=put_]");
     var body = {};
     bodyForm.forEach( element => {
       // I used split to separate prefix from worth name attribute
       var nameArray = element.getAttribute( "name" ).split( "_" );
       var name = nameArray[ nameArray.length - 1 ];
       if ( element.tagName != "TEXTAREA" ) {
         var value = element.getAttribute( "value" );
       } else {
       // if element is textarea, value attribute may return null or undefined
         var value = element.innerHTML;
       }
       // all elements with name="put_*" has value registered in body object
       body[ name ] = value;
     } );
     var xhr = new XMLHttpRequest();
     xhr.open( "PUT", url );
     xhr.setRequestHeader( "Content-Type", "application/json" );
     xhr.onload = () => {
       if ( xhr.status === 200 ) {
       // reload() uses cache, reload( true ) force no-cache. I reload the page to make "redirects normal effect" of HTML form when submit. You can manipulate DOM instead.
         location.reload( true );
       } else {
         console.log( xhr.status, xhr.responseText );
       }
     }
     xhr.send( body );
   }

   var deleteMethod = ( event ) => {
     event.preventDefault();
     var confirm = window.confirm( "Certeza em deletar este conteúdo?" );
     if ( confirm ) {
       var target = event.target;
       while ( target.tagName != "FORM" ) {
         target = target.parentElement;
       }
       var url = target.getAttribute( "action" );
       var xhr = new XMLHttpRequest();
       xhr.open( "DELETE", url );
       xhr.setRequestHeader( "Content-Type", "application/json" );
       xhr.onload = () => {
         if ( xhr.status === 200 ) {
           location.reload( true );
           console.log( xhr.responseText );
         } else {
           console.log( xhr.status, xhr.responseText );
         }
       }
       xhr.send();
     }
   }
</script>

이러한 함수가 정의되면 버튼에 이벤트 리스너를 추가하여 양식 메소드를 요청합니다.

<script>
  document.querySelectorAll( "[name=update_data], [name=delete_data]" ).forEach( element => {
    var button = element;
    var form = element;
    while ( form.tagName != "FORM" ) {
      form = form.parentElement;
    }
    var method = form.getAttribute( "method" );
    if ( method == "PUT" ) {
      button.addEventListener( "click", putMethod );
    }
    if ( method == "DELETE" ) {
      button.addEventListener( "click", deleteMethod );
    }
  } );
</script>

그리고 PUT 양식의 제거 버튼 :

<script>
  document.querySelectorAll( "[name=remove_data]" ).forEach( element => {
    var button = element;
    button.addEventListener( "click", deleteMethod );
</script>

_-----------

이 기사 https://blog.garstasio.com/you-dont-need-jquery/ajax/는 나를 많이 도와줍니다!

이 외에도 postMethod 함수 및 getMethod를 설정하여 브라우저 기본 동작 대신 POST 및 GET 제출 메소드를 처리 할 수 ​​있습니다. location.reload()성공적인 변경 메시지 표시 또는 성공적인 삭제와 같이 대신 원하는대로 수행 할 수 있습니다 .

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

JSFiddle : https://jsfiddle.net/enriquerene/d6jvw52t/53/

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.