Window.open i przekaż parametry metodą post


101

Metodą window.open otwieram nową stronę z parametrami, które muszę przekazać metodą post. Znalazłem rozwiązanie, ale niestety nie działa. To jest mój kod:

<script  type="text/javascript">    
function openWindowWithPost(url,name,keys,values)
{
    var newWindow = window.open(url, name);

    if (!newWindow) return false;

    var html = "";
    html += "<html><head></head><body><form id='formid' method='post' action='" + url +"'>";

    if (keys && values && (keys.length == values.length))
        for (var i=0; i < keys.length; i++)
            html += "<input type='hidden' name='" + keys[i] + "' value='" + values[i] + "'/>";

    html += "</form><script type='text/javascript'>document.getElementById(\"formid\").submit()</sc"+"ript></body></html>";

    newWindow.document.write(html);
    return newWindow;
}
</script>  

Następnie tworzę tablice:

<script type="text/javascript">    
var values= new Array("value1", "value2", "value3") 
var keys= new Array("a","b","c") 
</script>  

I wywołać funkcję przez:

<input id="Button1" type="button" value="Pass values" onclick="openWindowWithPost('test.asp','',keys,values)" />   

Ale kiedy klikam ten przycisk, witryna test.asp jest pusta (oczywiście próbuję uzyskać wartości pass - Request.Form("b")).

Jak mogę rozwiązać ten problem, dlaczego nie mogę uzyskać wartości pass?


2
Co nie działa? Zapisałem kopię na jsfiddle.net/TZMMF i działa zgodnie z oczekiwaniami.
wstać

Dzięki za odpowiedź. Tak, przepraszam - powyższy kod działa. Ale testuję tę funkcję za pomocą tablicy kluczy: <script type = "text / javascript"> var values ​​= new Array ("value1", "value2", "value3") var keys = new Array ("1", "2 "," 3 ") // zamiast a, b, c </script> Otrzymuję wartość przez Request.Form (" 2 ") W IE i Firefox otrzymuję pustą stronę.
luk4443

Odpowiedzi:


121

Zamiast pisać formularz w nowym oknie (co jest trudne do poprawienia, z kodowaniem wartości w kodzie HTML), po prostu otwórz puste okno i prześlij do niego formularz.

Przykład:

<form id="TheForm" method="post" action="test.asp" target="TheWindow">
<input type="hidden" name="something" value="something" />
<input type="hidden" name="more" value="something" />
<input type="hidden" name="other" value="something" />
</form>

<script type="text/javascript">
window.open('', 'TheWindow');
document.getElementById('TheForm').submit();
</script>

Edytować:

Aby dynamicznie ustawić wartości w formularzu, możesz wykonać następujące czynności:

function openWindowWithPost(something, additional, misc) {
  var f = document.getElementById('TheForm');
  f.something.value = something;
  f.more.value = additional;
  f.other.value = misc;
  window.open('', 'TheWindow');
  f.submit();
}

Aby opublikować formularz, wywołujesz funkcję z wartościami, takimi jak openWindowWithPost('a','b','c');.

Uwaga: zmieniłem nazwy parametrów w stosunku do nazw formularzy, aby pokazać, że nie muszą być takie same. Zwykle trzymasz je podobnie, aby ułatwić śledzenie wartości.


Dokładnie o tym myślałem. Wysłany oryginalny kod wydawał się jednak działać ... z wyjątkiem IE.
wstać

Dzięki za odpowiedź. Ale mam tabelę, w której w kolumnie są przyciski. Po kliknięciu tego przycisku otwieram nową stronę i przekazuję parametry. Muszę więc napisać funkcję, a dla każdego przycisku wywołać ją i przekazać ustalone argumenty. Moje pytanie, jak mogę przepisać Twój powyższy kod, aby działał?
luk4443

1
@ luk4443: Jeśli użyjesz adresu URL podczas otwierania okna, strona zostanie po prostu zastąpiona po wysłaniu formularza. Umieść adres URL we actionwłaściwości formularza.
Guffa

1
@Guffa w jakikolwiek sposób symulować również zachowanie target="_blank"?
everton

2
@EvertonAgner: Użyj unikalnej nazwy dla okna, a będzie działać jako _blank.
Guffa

62

Ponieważ chciałeś, aby cały formularz był wewnątrz javascript, zamiast pisać go w tagach, możesz zrobić to:

var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", "openData.do");

form.setAttribute("target", "view");

var hiddenField = document.createElement("input"); 
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", "message");
hiddenField.setAttribute("value", "val");
form.appendChild(hiddenField);
document.body.appendChild(form);

window.open('', 'view');

form.submit();

5
Brak implementacji opartej na jQuery i Pure JavaScript. Dzięki.
Pawan Pillai,

2
Strona @Mercenary jest otwarta w nowej karcie tutaj, czy mogę otworzyć stronę w nowym oknie podręcznym?
Yaje

30

Mimo że spóźniłem się o 3 lata, ale żeby uprościć przykład Guffy, nie musisz w ogóle mieć formularza na stronie:

$('<form method="post" action="test.asp" target="TheWindow">
       <input type="hidden" name="something" value="something">
       ...
   </form>').submit();

Edytowano:

$('<form method="post" action="test.asp" target="TheWindow">
       <input type="hidden" name="something" value="something">
       ...
   </form>').appendTo('body').submit().remove();

Może pomocna wskazówka dla kogoś :)


7
To rozwiązanie jest niepełne. Należy najpierw dodać do tego formularza treść, a następnie przesłać ją. Więc gdzie jest napisane .submit (); powinien brzmieć .appendTo ('body'). submit ();
Jonathan van de Veen

2
Bez tej części $("body").append(form);to nie zadziała
Axel

5
Jeśli dodasz .remove()po sugestii Jonathana .appendTo('body').submit(), posprzątasz nawet po sobie i nie zaśmiecisz bieżącej strony obiektami formularzy.
Simon,

26

Całkowicie zgadzam się z odpowiedzią najemnika zamieszczoną powyżej i stworzyłem dla mnie tę funkcję, która działa dla mnie. To nie jest odpowiedź, to komentarz najemnika do powyższego postu

function openWindowWithPostRequest() {
  var winName='MyWindow';
  var winURL='search.action';
  var windowoption='resizable=yes,height=600,width=800,location=0,menubar=0,scrollbars=1';
  var params = { 'param1' : '1','param2' :'2'};         
  var form = document.createElement("form");
  form.setAttribute("method", "post");
  form.setAttribute("action", winURL);
  form.setAttribute("target",winName);  
  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);
    }
  }              
  document.body.appendChild(form);                       
  window.open('', winName,windowoption);
  form.target = winName;
  form.submit();                 
  document.body.removeChild(form);           
}

12

Możesz po prostu użyć target="_blank"w formularzu.

<form action="action.php" method="post" target="_blank">
    <input type="hidden" name="something" value="some value">
</form>

Dodaj ukryte dane wejściowe w preferowany sposób, a następnie prześlij formularz za pomocą JS.


Ponadto, ponieważ window.openzostanie zablokowany jako wyskakujące okienko, gdy nie zostanie wywołany w clickmodule obsługi (lub jakimkolwiek innym zdarzeniu wywołanym przez użytkownika)
Xenos

4

Stworzyłem funkcję do generowania formularza na podstawie adresu URL, celu i obiektu jako metody POST/ GETdata i submit. Obsługuje zagnieżdżone i mieszane typy w tym obiekcie, dzięki czemu może w pełni replikować dowolną strukturę, którą go zasilasz: PHP automatycznie analizuje ją i zwraca jako zagnieżdżoną tablicę. Jest jednak jedno ograniczenie: nawiasy [i ]nie mogą być częścią żadnego klucza w obiekcie (np {"this [key] is problematic" : "hello world"}.). Jeśli ktoś wie, jak z tego uciec, proszę powiedz!

Bez zbędnych ceregieli, oto źródło:

Przykład użycia:

document.body.onclick = function() {
  var obj = {
    "a": [1, 2, [3, 4]],
    "b": "a",
    "c": {
      "x": [1],
      "y": [2, 3],
      "z": [{
        "a": "Hello",
        "b": "World"
      }, {
        "a": "Hallo",
        "b": "Welt"
      }]
    }
  };

  var form = getForm("http://example.com", "_blank", obj, "post");

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


Ups, adres URL w przykładzie użycia był nieprawidłowy. jeśli to naprawiono, więc nie ma więcej błędów.
Ceremonia

1
Nadal wygląda na uszkodzony, pojawia się pusta strona.
Adam Parkin

2

Znalazłem lepszy sposób na przekazywanie parametrów do wyskakującego okienka, a nawet pobieranie z niego parametrów:

Na stronie głównej:

var popupwindow;
var sharedObject = {};

function openPopupWindow()
{
   // Define the datas you want to pass
   sharedObject.var1 = 
   sharedObject.var2 = 
   ...

   // Open the popup window
   window.open(URL_OF_POPUP_WINDOW, NAME_OF_POPUP_WINDOW, POPUP_WINDOW_STYLE_PROPERTIES);
   if (window.focus) { popupwindow.focus(); }
}

function closePopupWindow()
{
    popupwindow.close();

    // Retrieve the datas from the popup window
    = sharedObject.var1;
    = sharedObject.var2;
    ...
}

W wyskakującym okienku:

var sharedObject = window.opener.sharedObject;

// function you have to to call to close the popup window
function myclose()
{
    //Define the parameters you want to pass to the main calling window
    sharedObject.var1 = 
    sharedObject.var2 = 
    ...
    window.opener.closePopupWindow();
}

Otóż ​​to !

Jest to bardzo wygodne, ponieważ:

  • Nie musisz ustawiać parametrów w adresie URL wyskakującego okienka.
  • Brak formy do zdefiniowania
  • Możesz używać nieograniczonych parametrów nawet obiektów.
  • Dwukierunkowy: możesz przekazywać parametry ORAZ, jeśli chcesz, możesz odzyskać nowe parametry.
  • Bardzo łatwe do wdrożenia.

Baw się dobrze!


uwaga: window.openernie jest obsługiwane przez wszystkie przeglądarki.
Raptor

1

Chciałem to zrobić w Reakcie, używając zwykłego Js i wypełniacza polifetch . OP nie powiedział, że specjalnie chciał utworzyć formularz i wywołać na nim metodę przesyłania, więc zrobiłem to, publikując wartości formularza jako json:

examplePostData = {
    method: 'POST',
    headers: {
       'Content-type' : 'application/json',
       'Accept' : 'text/html'
    },
    body: JSON.stringify({
        someList: [1,2,3,4],
        someProperty: 'something',
        someObject: {some: 'object'}
    })
}

asyncPostPopup = () => {

    //open a new window and set some text until the fetch completes
    let win=window.open('about:blank')
    writeToWindow(win,'Loading...')

    //async load the data into the window
    fetch('../postUrl', this.examplePostData)
    .then((response) => response.text())
    .then((text) => writeToWindow(win,text))
    .catch((error) => console.log(error))
}

writeToWindow = (win,text) => {
    win.document.open()
    win.document.write(text)
    win.document.close()
}


0

Używałem tego w przeszłości, ponieważ do kodowania zazwyczaj używamy składni maszynki do golenia

@using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { target = "_blank" }))

{

// dodaj tutaj ukryty i wypełniony formularz

}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.