Window.open e passa parâmetros por método post

97

Com o método window.open abro um novo site com parâmetros, que tenho que passar pelo método post. Encontrei a solução, mas infelizmente não funciona. Este é o meu código:

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

Em seguida, crio matrizes:

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

E chamar a função por:

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

Mas, quando clico neste botão, o site test.asp está vazio (é claro que tento obter valores de aprovação - Request.Form("b")).

Como eu poderia resolver esse problema, por que não consigo passar valores?

luk4443
fonte
2
O que não está funcionando? Salvei uma cópia em jsfiddle.net/TZMMF e funciona conforme o esperado.
favor, fique
Obrigado pela resposta. Sim, desculpe - o código acima funciona. Mas eu testo essa função com uma matriz de chaves: <script type = "text / javascript"> var values ​​= new Array ("value1", "value2", "value3") var keys = new Array ("1", "2 "," 3 ") // no lugar de a, b, c </script> eu obtenho o valor por Request.Form (" 2 ") No IE e Firefox eu obtenho uma página vazia.
luk4443

Respostas:

121

Em vez de escrever um formulário na nova janela (o que é difícil de corrigir, com codificação de valores no código HTML), basta abrir uma janela vazia e postar um formulário nela.

Exemplo:

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

Editar:

Para definir os valores no formulário dinamicamente, você pode fazer assim:

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

Para postar o formulário você chama a função com os valores, como openWindowWithPost('a','b','c');.

Nota: Eu variei os nomes dos parâmetros em relação aos nomes dos formulários para mostrar que eles não precisam ser iguais. Normalmente, você os manteria semelhantes uns aos outros para tornar mais simples o rastreamento dos valores.

Guffa
fonte
Isso é exatamente o que eu estava pensando. O código original postado parecia funcionar ... exceto no IE.
favor, fique em
Obrigado pela resposta. Mas eu tenho uma tabela, onde na coluna estão os botões. Quando clico neste botão, abro uma nova página e passo alguns parâmetros. Portanto, tenho que escrever a função e, para cada botão, chamá-la e passar argumentos fixos. Minha pergunta, como eu poderia reescrever seu código acima para funcionar?
luk4443,
1
@ luk4443: Se você usar o URL ao abrir a janela, a página será substituída apenas quando você postar o formulário. Coloque o URL na actionpropriedade do formulário.
Guffa
1
@Guffa alguma forma de simular também o comportamento de target="_blank"?
Everton de
2
@EvertonAgner: Use um nome exclusivo para a janela e ela funcionará como _blank.
Guffa
62

Como você queria todo o formulário dentro do javascript, em vez de escrevê-lo em tags, você pode fazer isso:

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();
Mercenário
fonte
5
Nenhuma implementação baseada em jQuery e Pure JavaScript. Obrigado.
Pawan Pillai
2
A página @Mercenary está aberta em uma nova guia aqui, posso abrir a página em uma nova janela pop-up?
Yaje
29

Mesmo que eu esteja 3 anos atrasado, mas para simplificar o exemplo de Guffa, você nem precisa ter o formulário na página:

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

Editado:

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

Talvez uma dica útil para alguém :)

Andrius Naruševičius
fonte
7
Esta solução está incompleta. Deve primeiro adicionar este formulário ao corpo e depois enviá-lo. Então, onde diz .submit (); deve ser .appendTo ('body'). submit ();
Jonathan van de Veen
1
Sem esta parte $("body").append(form);não funcionará
Axel
4
Se você adicionar um .remove()após a sugestão de Jonathan .appendTo('body').submit(), você mesmo limpará sua própria imagem e não confundirá a página atual com objetos de formulário.
Simon
24

Eu concordo totalmente com a resposta do mercenário postada acima e criei esta função para mim que funciona para mim. Não é uma resposta, é um comentário na postagem acima do mercenário

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);           
}
Youdhveer
fonte
12

Você pode simplesmente usar target="_blank"no formulário.

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

Adicione entradas ocultas da maneira que preferir e, a seguir, simplesmente envie o formulário com JS.

Cais
fonte
Além disso, como window.openseria bloqueado como um pop-up, quando não fosse chamado dentro de um clickmanipulador (ou qualquer evento disparado pelo usuário como esse)
Xenos
4

Criei uma função para gerar um formulário, baseado em url, destino e um objeto como o método POST/ GETdata e submit. Ele suporta tipos aninhados e mistos dentro desse objeto, portanto, pode replicar totalmente qualquer estrutura que você alimenta: o PHP automaticamente analisa e retorna como um array aninhado. No entanto, há uma única restrição: os colchetes [e ]não devem fazer parte de nenhuma chave no objeto (como {"this [key] is problematic" : "hello world"}). Se alguém souber como escapar adequadamente, diga!

Sem mais delongas, aqui está a fonte:

Exemplo de uso:

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

Cerimônia
fonte
opa, o URL no exemplo de uso estava malformado. se corrigido, então não há mais erro.
Cerimônia de
1
Ainda parece quebrado, estou recebendo uma página em branco.
Adam Parkin
2

Descobri uma maneira melhor de passar parâmetros para a janela pop-up e até mesmo recuperar parâmetros dela:

Na página principal:

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

Na janela pop-up:

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

É isso aí !

E isso é muito conveniente porque:

  • Você não precisa definir parâmetros no URL da janela pop-up.
  • Sem forma para definir
  • Você pode usar parâmetros ilimitados até objetos.
  • Bi-direcional: você pode passar parâmetros E, se quiser, pode recuperar novos parâmetros.
  • Muito fácil de implementar.

Diverta-se!

Homem azul
fonte
nota: window.openernão é compatível com todos os navegadores.
Raptor
1

Eu queria fazer isso no React usando Js simples e o fetch polyfill . OP não disse que queria especificamente criar um formulário e invocar o método submit nele, então fiz isso postando os valores do formulário como 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()
}

fonte
0

A ação de envio padrão é Ext.form.action.Submit, que usa uma solicitação Ajax para enviar os valores do formulário para uma URL configurada. Para habilitar o envio normal do navegador de um formulário Ext, use a opção de configuração standardSubmit.

Link: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.Basic-cfg-standardSubmit

solução: coloque standardSubmit: true em sua configuração. Espero que isso ajude você :)

user2420964
fonte
0

Eu usei isso no passado, uma vez que normalmente usamos a sintaxe de razor para codificação

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

{

// adicionar oculto e formulário arquivado aqui

}

resgates
fonte