Window.open et passer les paramètres par méthode post


97

Avec la méthode window.open, j'ouvre un nouveau site avec des paramètres, que je dois passer par la méthode post.J'ai trouvé une solution, mais malheureusement cela ne fonctionne pas. Voici mon code:

<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>  

Ensuite, je crée des tableaux:

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

Et appelez la fonction par:

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

Mais, lorsque je clique sur ce bouton, le site test.asp est vide (bien sûr, j'essaye d'obtenir des valeurs de réussite - Request.Form("b")).

Comment pourrais-je résoudre ce problème, pourquoi je ne peux pas obtenir de valeurs de réussite?


2
Qu'est-ce qui ne marche pas? J'ai enregistré une copie sur jsfiddle.net/TZMMF et cela fonctionne comme prévu.
PleaseStand

Merci pour votre réponse. Oui, désolé - le code ci-dessus fonctionne. Mais je teste cette fonction avec un tableau de clés: <script type = "text / javascript"> var values ​​= new Array ("value1", "value2", "value3") var keys = new Array ("1", "2 "," 3 ") // à la place de a, b, c </script> J'obtiens une valeur par Request.Form (" 2 ") Dans IE et Firefox, j'obtiens une page vide.
luk4443

Réponses:


121

Au lieu d'écrire un formulaire dans la nouvelle fenêtre (ce qui est difficile à obtenir, avec l'encodage des valeurs dans le code HTML), ouvrez simplement une fenêtre vide et postez-y un formulaire.

Exemple:

<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>

Éditer:

Pour définir les valeurs du formulaire de manière dynamique, vous pouvez procéder comme suit:

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();
}

Pour publier le formulaire, vous appelez la fonction avec les valeurs, comme openWindowWithPost('a','b','c');.

Remarque: j'ai modifié les noms de paramètres par rapport aux noms de formulaires pour montrer qu'ils ne doivent pas nécessairement être identiques. Habituellement, vous les gardez similaires les uns aux autres pour simplifier le suivi des valeurs.


C'est exactement ce que je pensais. Le code original publié semble cependant fonctionner ... sauf sur IE.
PleaseStand

Merci pour votre réponse. Mais j'ai une table, où en colonne se trouvent des boutons. Lorsque je clique sur ce bouton, j'ouvre une nouvelle page et passe quelques paramètres. Je dois donc écrire une fonction, et pour chaque bouton, appelez-la et passez des arguments fixes. Ma question, comment pourrais-je réécrire votre code ci-dessus pour qu'il fonctionne?
luk4443

1
@ luk4443: Si vous utilisez l'URL lorsque vous ouvrez la fenêtre, la page sera simplement remplacée lorsque vous postez le formulaire. Mettez l'URL dans la actionpropriété du formulaire.
Guffa

1
@Guffa n'importe quel moyen de simuler également le comportement de target="_blank"?
everton

2
@EvertonAgner: utilisez un nom unique pour la fenêtre, et cela fonctionnera comme _blank.
Guffa

62

Puisque vous vouliez tout le formulaire dans le javascript, au lieu de l'écrire dans des balises, vous pouvez faire ceci:

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
Pas d'implémentation basée sur jQuery et Pure JavaScript. Merci.
Pawan Pillai

2
La page @Mercenaire est ouverte dans un nouvel onglet ici, puis-je ouvrir la page dans une nouvelle fenêtre contextuelle?
Yaje

29

Même si j'ai 3 ans de retard, mais pour simplifier l'exemple de Guffa, vous n'avez même pas besoin d'avoir le formulaire sur la page du tout:

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

Édité:

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

Peut-être un conseil utile pour quelqu'un :)


7
Cette solution est incomplète. Il doit d'abord ajouter ce formulaire au corps, puis le soumettre. Alors où il est dit .submit (); il devrait dire .appendTo ('body'). submit ();
Jonathan van de Veen

1
Sans cette partie, $("body").append(form);cela ne fonctionnera pas
Axel

4
Si vous ajoutez un .remove()après la suggestion de Jonathan .appendTo('body').submit(), vous nettoierez même après vous-même et n'encombrerez pas la page actuelle avec des objets de formulaire.
Simon

24

Je suis entièrement d'accord avec la réponse de mercenaire publiée ci-dessus et j'ai créé cette fonction pour moi qui fonctionne pour moi. Ce n'est pas une réponse, c'est un commentaire sur le post ci-dessus par un mercenaire

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

Vous pouvez simplement utiliser target="_blank"sur le formulaire.

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

Ajoutez des entrées masquées comme vous le souhaitez, puis soumettez simplement le formulaire avec JS.


De plus, puisque window.openserait bloqué en tant que popup, lorsqu'il n'est pas appelé dans un clickgestionnaire (ou tout événement déclenché par l'utilisateur comme celui-ci)
Xenos

4

J'ai créé une fonction pour générer un formulaire, basé sur l'url, la cible et un objet comme méthode POST/ GETdata et submit. Il prend en charge les types imbriqués et mixtes dans cet objet, de sorte qu'il peut répliquer entièrement toute structure que vous le nourrissez: PHP l'analyse automatiquement et le renvoie sous forme de tableau imbriqué. Cependant, il y a une seule restriction: les crochets [et ]ne doivent faire partie d'aucune clé de l'objet (comme {"this [key] is problematic" : "hello world"}). Si quelqu'un sait comment y échapper correctement, dites-le!

Sans plus tarder, voici la source:

Exemple d'utilisation:

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);
}


Oups, l'URL de l'exemple d'utilisation était mal formée. s'il est corrigé, il n'y a donc plus d'erreur.
Cérémonie le

1
Semble toujours cassé, je reçois une page blanche.
Adam Parkin

2

J'ai trouvé un meilleur moyen de passer des paramètres à la fenêtre contextuelle et même d'en récupérer des paramètres:

Dans la page principale:

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;
    ...
}

Dans la fenêtre contextuelle:

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();
}

C'est tout !

Et c'est très pratique car:

  • Vous ne devez pas définir de paramètres dans l'URL de la fenêtre contextuelle.
  • Aucune forme à définir
  • Vous pouvez utiliser des paramètres illimités même des objets.
  • Bidirectionnel: vous pouvez passer des paramètres ET, si vous le souhaitez, récupérer de nouveaux paramètres.
  • Très facile à mettre en œuvre.

S'amuser!


Remarque: window.openern'est pas pris en charge par tous les navigateurs.
Raptor

1

Je voulais faire cela dans React en utilisant des Js simples et le fetch polyfill . OP n'a pas dit qu'il voulait spécifiquement créer un formulaire et invoquer la méthode submit dessus, donc je l'ai fait en publiant les valeurs du formulaire en tant que 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

Je l'ai utilisé dans le passé, car nous utilisons généralement la syntaxe de rasoir pour le codage

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

{

// ajouter caché et formulaire déposé ici

}

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.