javascript - 페이지 이동없이 url 변경




양식 제출과 같은 자바 스크립트 게시물 요청 (19)

브라우저를 다른 페이지로 연결하려고합니다. GET 요청을 원한다면

document.location.href = 'http://example.com/q=a';

하지만 내가 액세스하려고하는 리소스는 POST 요청을 사용하지 않으면 올바르게 응답하지 않습니다. 이것이 동적으로 생성되지 않으면 HTML을 사용할 수 있습니다.

<form action="http://example.com/" method="POST">
  <input type="hidden" name="q" value="a">
</form>

그런 다음 DOM에서 양식을 제출하기 만하면됩니다.

하지만 실제로 JavaScript 코드를 사용하면

post_to_url('http://example.com/', {'q':'a'});

최고의 크로스 브라우저 구현은 무엇입니까?

편집하다

나는 분명치 않다. 폼을 제출하는 것처럼 브라우저의 위치를 ​​변경하는 솔루션이 필요합니다. 이것이 XMLHttpRequest 에서 가능하다면 분명하지 않습니다. 그리고 이것은 비동기 적이거나 XML을 사용해서는 안되기 때문에 Ajax가 대답이 될 수 없습니다.


@Aaron의 간단하고 빠른 구현 :

document.body.innerHTML += '<form id="dynForm" action="http://example.com/" method="post"><input type="hidden" name="q" value="a"></form>';
document.getElementById("dynForm").submit();

물론, Prototype 또는 jQuery 와 같은 JavaScript 프레임 워크를 사용해야합니다.


AJAX 호출을 만들 수 있습니다 (예 : Prototype.js 또는 JQuery를 사용하는 라이브러리 사용). AJAX는 GET 및 POST 옵션을 모두 처리 할 수 ​​있습니다.


POST 또는 GET으로 리다이렉트하기위한 jQuery 플러그인 :

github.com/mgalante/jquery.redirect/blob/master/…

테스트하려면 위의 .js 파일을 포함 시키거나 클래스에 코드를 복사 / 붙여 넣기 한 다음 여기에 코드를 사용하고 "args"를 변수 이름으로 바꾸고 "values"를 해당 변수의 값으로 대체하십시오.

$.redirect('demo.php', {'arg1': 'value1', 'arg2': 'value2'});

jQuery 및 $ .post 메서드 와 같은 라이브러리를 사용할 수 있습니다.


글쎄, 내가 Rakesh Pai의 대답으로 이것을 만들 때 시간을 잃지 않았으므로 나는 다른 모든 글을 읽었 으면 좋겠다. 다음은 배열과 객체에서 작동하는 재귀 적 솔루션입니다. jQuery에 대한 의존성이 없습니다.

전체 양식을 배열처럼 제출해야하는 경우를 처리 할 세그먼트를 추가했습니다. (즉, 항목 목록 주위에 래퍼 객체가없는 경우)

/**
 * Posts javascript data to a url using form.submit().  
 * Note: Handles json and arrays.
 * @param {string} path - url where the data should be sent.
 * @param {string} data - data as javascript object (JSON).
 * @param {object} options -- optional attributes
 *  { 
 *    {string} method: get/post/put/etc,
 *    {string} arrayName: name to post arraylike data.  Only necessary when root data object is an array.
 *  }
 * @example postToUrl('/UpdateUser', {Order {Id: 1, FirstName: 'Sally'}});
 */
function postToUrl(path, data, options) {
    if (options === undefined) {
        options = {};
    }

    var method = options.method || "post"; // Set method to post by default if not specified.

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    function constructElements(item, parentString) {
        for (var key in item) {
            if (item.hasOwnProperty(key) && item[key] != null) {
                if (Object.prototype.toString.call(item[key]) === '[object Array]') {
                    for (var i = 0; i < item[key].length; i++) {
                        constructElements(item[key][i], parentString + key + "[" + i + "].");
                    }
                } else if (Object.prototype.toString.call(item[key]) === '[object Object]') {
                    constructElements(item[key], parentString + key + ".");
                } else {
                    var hiddenField = document.createElement("input");
                    hiddenField.setAttribute("type", "hidden");
                    hiddenField.setAttribute("name", parentString + key);
                    hiddenField.setAttribute("value", item[key]);
                    form.appendChild(hiddenField);
                }
            }
        }
    }

    //if the parent 'data' object is an array we need to treat it a little differently
    if (Object.prototype.toString.call(data) === '[object Array]') {
        if (options.arrayName === undefined) console.warn("Posting array-type to url will doubtfully work without an arrayName defined in options.");
        //loop through each array item at the parent level
        for (var i = 0; i < data.length; i++) {
            constructElements(data[i], (options.arrayName || "") + "[" + i + "].");
        }
    } else {
        //otherwise treat it normally
        constructElements(data, "");
    }

    document.body.appendChild(form);
    form.submit();
};

나는 document.forms java를 사용하고 폼의 모든 요소를 ​​얻기 위해 반복 한 다음 xhttp를 통해 보낸다. 그래서 이것은 javascript / ajax에 대한 내 솔루션입니다 (모든 HTML이 예제로 포함되어 있습니다).

          <!DOCTYPE html>
           <html>
           <body>
           <form>
       First name: <input type="text" name="fname" value="Donald"><br>
        Last name: <input type="text" name="lname" value="Duck"><br>
          Addr1: <input type="text" name="add" value="123 Pond Dr"><br>
           City: <input type="text" name="city" value="Duckopolis"><br>
      </form> 



           <button onclick="smc()">Submit</button>

                   <script>
             function smc() {
                  var http = new XMLHttpRequest();
                       var url = "yourphpfile.php";
                     var x = document.forms[0];
                          var xstr = "";
                         var ta ="";
                    var tb ="";
                var i;
               for (i = 0; i < x.length; i++) {
     if (i==0){ta = x.elements[i].name+"="+ x.elements[i].value;}else{
       tb = tb+"&"+ x.elements[i].name +"=" + x.elements[i].value;
             } }

           xstr = ta+tb;
      http.open("POST", url, true);
       http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

      http.onreadystatechange = function() {
          if(http.readyState == 4 && http.status == 200) {

        // do whatever you want to with the html output response here

                } 

               }
            http.send(xstr);

              }
         </script>

         </body>
     </html>

내 경우 완벽하게 작동합니다.

document.getElementById("form1").submit();

다음과 같은 함수에서 사용할 수 있습니다.

function formSubmit() {
     document.getElementById("frmUserList").submit();
} 

이것을 사용하여 모든 입력 값을 게시 할 수 있습니다.


내 솔루션은 @RakeshPai의 현재 허용되는 솔루션과 달리 깊게 중첩 된 객체를 인코딩합니다.

'qs'npm 라이브러리와 stringify 함수를 사용하여 중첩 된 객체를 매개 변수로 변환합니다.

이 코드는 Rails 백엔드에서 잘 작동하지만, stringify에 전달 된 옵션을 수정하여 필요한 백엔드에서 작동하도록 수정할 수 있어야합니다. Rails에서는 arrayFormat을 "대괄호"로 설정해야합니다.

import qs from "qs"

function normalPost(url, params) {
  var form = document.createElement("form");
  form.setAttribute("method", "POST");
  form.setAttribute("action", url);

  const keyValues = qs
    .stringify(params, { arrayFormat: "brackets", encode: false })
    .split("&")
    .map(field => field.split("="));

  keyValues.forEach(field => {
    var key = field[0];
    var value = field[1];
    var hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", key);
    hiddenField.setAttribute("value", value);
    form.appendChild(hiddenField);
  });
  document.body.appendChild(form);
  form.submit();
}

예:

normalPost("/people/new", {
      people: [
        {
          name: "Chris",
          address: "My address",
          dogs: ["Jordan", "Elephant Man", "Chicken Face"],
          information: { age: 10, height: "3 meters" }
        },
        {
          name: "Andrew",
          address: "Underworld",
          dogs: ["Doug", "Elf", "Orange"]
        },
        {
          name: "Julian",
          address: "In a hole",
          dogs: ["Please", "Help"]
        }
      ]
    });

다음 Rails 매개 변수를 생성합니다.

{"authenticity_token"=>"...",
 "people"=>
  [{"name"=>"Chris", "address"=>"My address", "dogs"=>["Jordan", "Elephant Man", "Chicken Face"], "information"=>{"age"=>"10", "height"=>"3 meters"}},
   {"name"=>"Andrew", "address"=>"Underworld", "dogs"=>["Doug", "Elf", "Orange"]},
   {"name"=>"Julian", "address"=>"In a hole", "dogs"=>["Please", "Help"]}]}

또 다른 반복적 인 해결책은 다른 것들 중 일부가 망가져있는 것 같기 때문에 (나는 그것들 모두를 테스트하지 않았다). 이것은 lodash 3.x 와 ES6 (jQuery 불필요)에 달려 있습니다 :

function createHiddenInput(name, value) {
    let input = document.createElement('input');
    input.setAttribute('type','hidden');
    input.setAttribute('name',name);
    input.setAttribute('value',value);
    return input;
}

function appendInput(form, name, value) {
    if(_.isArray(value)) {
        _.each(value, (v,i) => {
            appendInput(form, `${name}[${i}]`, v);
        });
    } else if(_.isObject(value)) {
        _.forOwn(value, (v,p) => {
            appendInput(form, `${name}[${p}]`, v);
        });
    } else {
        form.appendChild(createHiddenInput(name, value));
    }
}

function postToUrl(url, data) {
    let form = document.createElement('form');
    form.setAttribute('method', 'post');
    form.setAttribute('action', url);

    _.forOwn(data, (value, name) => {
        appendInput(form, name, value);
    });

    form.submit();
}

사용자를 자동으로 다른 페이지로 게시하고 안내하는 방법은 숨겨진 양식을 작성한 다음 자동 제출하는 것입니다. 숨겨진 양식은 웹 페이지에 아무런 공간도 확보하지 않도록하십시오. 코드는 다음과 같습니다.

    <form name="form1" method="post" action="somepage.php">
    <input name="fielda" type="text" id="fielda" type="hidden">

    <textarea name="fieldb" id="fieldb" cols="" rows="" style="display:none"></textarea>
</form>
    document.getElementById('fielda').value="some text for field a";
    document.getElementById('fieldb').innerHTML="some text for multiline fieldb";
    form1.submit();

자동 제출 신청

자동 제출의 응용 프로그램은 사용자가 자동으로 다른 페이지에서 해당 페이지로 다시 입력하는 양식 값을 지정합니다. 이러한 응용 프로그램은 다음과 같습니다.

fieldapost=<?php echo $_post['fielda'];>
if (fieldapost !="") {
document.write("<form name='form1' method='post' action='previouspage.php'>
  <input name='fielda' type='text' id='fielda' type='hidden'>
</form>");
document.getElementById('fielda').value=fieldapost;
form1.submit();
}

아니요, 양식 제출과 같은 자바 스크립트 게시 요청을 할 수 없습니다.

당신이 가질 수있는 것은 HTML 형식입니다. 그런 다음 JavaScript로 제출하십시오. (이 페이지에서 여러 번 설명했듯이)

HTML을 직접 작성할 수 있으며 HTML을 작성하는 데 JavaScript가 필요하지 않습니다. 사람들이 그 제안을한다면 어리석은 짓이다.

<form id="ninja" action="http://example.com/" method="POST">
  <input id="donaldduck" type="hidden" name="q" value="a">
</form>

당신의 기능은 단지 당신이 원하는 방식대로 양식을 구성합니다.

function postToURL(a,b,c){
   document.getElementById("ninja").action     = a;
   document.getElementById("donaldduck").name  = b;
   document.getElementById("donaldduck").value = c;
   document.getElementById("ninja").submit();
}

그런 다음 사용하십시오.

postToURL("http://example.com/","q","a");

그러나 나는 그 기능을 생략하고 그냥 할 것입니다.

   document.getElementById('donaldduck').value = "a";
   document.getElementById("ninja").submit();

마지막으로 스타일 결정은 ccs 파일에 있습니다.

.ninja{ 
  display:none;
}

개인적으로 양식은 이름으로 언급되어야한다고 생각하지만 지금은 중요하지 않습니다.


여기 내가 어떻게하는지.

function redirectWithPost(url, data){
        var form = document.createElement('form');
        form.method = 'POST';
        form.action = url;

        for(var key in data){
            var input = document.createElement('input');
            input.name = key;
            input.value = data[key];
            input.type = 'hidden';
            form.appendChild(input)
        }
        document.body.appendChild(form);
        form.submit();
    }

이것은 Alan의 옵션 2 (위)와 같습니다. httpobj를 인스턴스화하는 방법은 연습으로 남겨 둡니다.

httpobj.open("POST", url, true);
httpobj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
httpobj.onreadystatechange=handler;
httpobj.send(post);

이것은 jQuery를 사용하는 beauSD 코드를 기반으로합니다. 개체에 대해 재귀 적으로 작동하도록 향상되었습니다.

function post(url, params, urlEncoded, newWindow) {
    var form = $('<form />').hide();
    form.attr('action', url)
        .attr('method', 'POST')
        .attr('enctype', urlEncoded ? 'application/x-www-form-urlencoded' : 'multipart/form-data');
    if(newWindow) form.attr('target', '_blank');

    function addParam(name, value, parent) {
        var fullname = (parent.length > 0 ? (parent + '[' + name + ']') : name);
        if(value instanceof Object) {
            for(var i in value) {
                addParam(i, value[i], fullname);
            }
        }
        else $('<input type="hidden" />').attr({name: fullname, value: value}).appendTo(form);
    };

    addParam('', params, '');

    $('body').append(form);
    form.submit();
}

한 가지 해결책은 양식을 생성하여 제출하는 것입니다. 한 가지 구현은

function post_to_url(url, params) {
    var form = document.createElement('form');
    form.action = url;
    form.method = 'POST';

    for (var i in params) {
        if (params.hasOwnProperty(i)) {
            var input = document.createElement('input');
            input.type = 'hidden';
            input.name = i;
            input.value = params[i];
            form.appendChild(input);
        }
    }

    form.submit();
}

그래서 간단한 URL로 단축 책갈피를 구현할 수 있습니다.

javascript:post_to_url('http://is.gd/create.php', {'URL': location.href});

이 답변 에서 제공되는 createElement 함수를 사용하면 document.createElement 와 함께 정상적으로 생성 된 요소에 대한 name 속성 으로 인해 IE가 손상 되기 때문에 필요 document.createElement .

function postToURL(url, values) {
    values = values || {};

    var form = createElement("form", {action: url,
                                      method: "POST",
                                      style: "display: none"});
    for (var property in values) {
        if (values.hasOwnProperty(property)) {
            var value = values[property];
            if (value instanceof Array) {
                for (var i = 0, l = value.length; i < l; i++) {
                    form.appendChild(createElement("input", {type: "hidden",
                                                             name: property,
                                                             value: value[i]}));
                }
            }
            else {
                form.appendChild(createElement("input", {type: "hidden",
                                                         name: property,
                                                         value: value}));
            }
        }
    }
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
}

Prototype 라이브러리에는 JavaScript 객체 / 구조를 쉽게 쿼리 문자열 스타일 문자열로 변환 할 수있는 ".toQueryString ()"메서드가있는 Hashtable 객체가 포함되어 있습니다. 게시물은 요청의 "본문"이 쿼리 문자열 형식의 문자열이어야하므로 Ajax 요청이 게시물로 올바르게 작동 할 수 있습니다. 다음은 Prototype을 사용한 예제입니다.

$req = new Ajax.Request("http://foo.com/bar.php",{
    method: 'post',
    parameters: $H({
        name: 'Diodeus',
        question: 'JavaScript posts a request like a form request',
        ...
    }).toQueryString();
};

Prototype 설치되어있는 경우 다음과 같이 숨겨진 양식을 생성하여 제출하도록 코드를 강화할 수 있습니다.

 var form = new Element('form',
                        {method: 'post', action: 'http://example.com/'});
 form.insert(new Element('input',
                         {name: 'q', value: 'a', type: 'hidden'}));
 $(document.body).insert(form);
 form.submit();

 /**
 * sends a request to the specified url from a form. this will change the window location.
 * @param {string} path the path to send the post request to
 * @param {object} params the paramiters to add to the url
 * @param {string} [method=post] the method to use on the form
 */

function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }
    }

    document.body.appendChild(form);
    form.submit();
}

예:

post('/contact/', {name: 'Johnny Bravo'});

편집 :이 너무 많이 upvoted 얻은 이후, 사람들이 복사 - 붙여 넣기 많은 것 같아요. 그래서 부주의 한 버그를 수정하기 위해 hasOwnProperty 검사를 추가했습니다.





html-form