Window.open và truyền tham số bằng phương pháp post


97

Với phương thức window.open, tôi mở trang web mới với các tham số mà tôi phải chuyển bằng phương pháp post. Tôi đã tìm ra giải pháp, nhưng tiếc là nó không hoạt động. Đây là mã của tôi:

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

Tiếp theo, tôi tạo mảng:

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

Và gọi hàm bằng:

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

Tuy nhiên, khi tôi nhấp vào nút này, trang web test.asp trống (tất nhiên tôi thử lấy các giá trị vượt qua - Request.Form("b")).

Làm thế nào tôi có thể giải quyết vấn đề này, tại sao tôi không thể nhận được các giá trị vượt qua?


2
Cái gì không hoạt động? Tôi đã lưu một bản sao tại jsfiddle.net/TZMMF và nó hoạt động như mong đợi.
PleaseStand

Cảm ơn đã trả lời. Vâng, xin lỗi - mã trên hoạt động. Nhưng tôi kiểm tra chức năng này với mảng khóa: <script type = "text / javascript"> var values ​​= new Array ("value1", "value2", "value3") var key = new Array ("1", "2 "," 3 ") // thay cho a, b, c </script> Tôi nhận được giá trị bằng Request.Form (" 2 ") Trong IE và Firefox, tôi nhận được trang trống.
luk4443

Câu trả lời:


121

Thay vì viết biểu mẫu vào cửa sổ mới (rất khó để có được chính xác, với mã hóa các giá trị trong mã HTML), chỉ cần mở một cửa sổ trống và đăng biểu mẫu lên đó.

Thí dụ:

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

Biên tập:

Để đặt động các giá trị trong biểu mẫu, bạn có thể làm như sau:

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

Để đăng biểu mẫu, bạn gọi hàm với các giá trị, như openWindowWithPost('a','b','c');.

Lưu ý: Tôi đã thay đổi tên tham số liên quan đến tên biểu mẫu để cho thấy rằng chúng không nhất thiết phải giống nhau. Thông thường bạn sẽ giữ chúng tương tự nhau để dễ theo dõi các giá trị hơn.


Đó chính xác là những gì tôi đang nghĩ. Mặc dù vậy, mã gốc được đăng có vẻ hoạt động ... ngoại trừ trên IE.
PleaseStand

Cảm ơn đã trả lời. Nhưng tôi có một bảng, trong đó cột là các nút. Khi tôi nhấp vào nút này, tôi mở trang mới và chuyển một số thông số. Vì vậy, tôi phải viết hàm, và cho mỗi nút gọi nó và truyền các đối số cố định. Câu hỏi của tôi, làm thế nào tôi có thể viết lại mã trên của bạn để hoạt động?
luk4443

1
@ luk4443: Nếu bạn sử dụng URL khi mở cửa sổ, trang sẽ chỉ được thay thế khi bạn đăng biểu mẫu. Đặt URL trong thuộc actiontính của biểu mẫu.
Guffa

1
@Guffa bất kỳ cách nào để cũng mô phỏng hành vi của target="_blank"?
everton

2
@EvertonAgner: Sử dụng một tên duy nhất cho cửa sổ và nó sẽ hoạt động như vậy _blank.
Guffa

62

Vì bạn muốn toàn bộ biểu mẫu bên trong javascript, thay vì viết nó trong các thẻ, bạn có thể làm điều này:

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
Không có triển khai dựa trên jQuery và JavaScript thuần túy. Cảm ơn.
Pawan Pillai

2
Trang @Mercenary đang mở trong tab mới tại đây, tôi có thể mở trang trong cửa sổ bật lên mới không?
Yaje

29

Mặc dù tôi đã trễ 3 năm, nhưng để đơn giản hóa ví dụ của Guffa, bạn thậm chí không cần phải có biểu mẫu trên trang:

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

Đã chỉnh sửa:

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

Có thể là một mẹo hữu ích cho ai đó :)


7
Giải pháp này không đầy đủ. Đầu tiên nó phải thêm nội dung của biểu mẫu này và sau đó gửi nó. Vì vậy, nơi nó nói .submit (); nó sẽ nói .appendTo ('body'). submit ();
Jonathan van de Veen,

1
Nếu không có phần này $("body").append(form);nó sẽ không hoạt động
Axel

4
Nếu bạn thêm dấu .remove()sau Jonathan được đề xuất .appendTo('body').submit(), bạn thậm chí sẽ tự dọn dẹp và không làm lộn xộn trang hiện tại với các đối tượng biểu mẫu.
Simon

24

Tôi hoàn toàn đồng ý với câu trả lời của lính đánh thuê được đăng ở trên và đã tạo cho tôi chức năng này phù hợp với tôi. Nó không phải là một câu trả lời, đó là một bình luận trên bài đăng trên của lính đánh thuê

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

Bạn chỉ có thể sử dụng target="_blank"trên biểu mẫu.

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

Thêm đầu vào ẩn theo cách bạn thích, sau đó chỉ cần gửi biểu mẫu bằng JS.


Hơn nữa kể từ window.opensẽ bị chặn như một popup, khi không được gọi bên trong một clickhandler (hoặc bất kỳ người sử dụng bắn sự kiện như thế)
Xenos

4

Tôi đã tạo một hàm để tạo một biểu mẫu, dựa trên url, đích và một đối tượng làm phương thức POST/ GETdata và submit. Nó hỗ trợ các kiểu lồng nhau và hỗn hợp bên trong đối tượng đó, vì vậy nó hoàn toàn có thể sao chép bất kỳ cấu trúc nào bạn cung cấp cho nó: PHP tự động phân tích cú pháp nó và trả về nó dưới dạng một mảng lồng nhau. Tuy nhiên, có một hạn chế duy nhất: các dấu ngoặc []không được là một phần của bất kỳ khóa nào trong đối tượng (như {"this [key] is problematic" : "hello world"}). Nếu ai đó biết làm thế nào để thoát khỏi nó đúng cách, xin vui lòng cho biết!

Không cần quảng cáo thêm, đây là nguồn:

Ví dụ sử dụng:

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


rất tiếc, URL trong ví dụ sử dụng không đúng định dạng. nếu sửa nó, do đó không có lỗi nữa.
Lễ

1
Vẫn có vẻ bị hỏng, tôi nhận được một trang trống.
Adam Parkin

2

Tôi đã tìm thấy một cách tốt hơn để chuyển các tham số vào cửa sổ bật lên và thậm chí để truy xuất các tham số từ nó:

Trong trang chính:

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

Trong cửa sổ bật lên:

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

Đó là nó !

Và điều này rất thuận tiện vì:

  • Bạn không phải đặt các tham số trong URL của cửa sổ bật lên.
  • Không có hình thức để xác định
  • Bạn có thể sử dụng các tham số không xác định ngay cả đối tượng.
  • Bi-directionnal: bạn có thể truyền tham số AND, nếu muốn, bạn có thể truy xuất tham số mới.
  • Rất dễ thực hiện.

Chúc vui vẻ!


lưu ý: window.openerkhông được hỗ trợ từ tất cả các trình duyệt.
Raptor

1

Tôi muốn thực hiện việc này trong React bằng cách sử dụng J đơn giản và polyfill tìm nạp . OP không nói rằng anh ấy đặc biệt muốn tạo một biểu mẫu và gọi phương thức gửi trên đó, vì vậy tôi đã thực hiện bằng cách đăng các giá trị biểu mẫu dưới dạng 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

Hành động gửi mặc định là Ext.form.action.Submit, sử dụng một yêu cầu Ajax để gửi các giá trị của biểu mẫu đến một URL được định cấu hình. Để kích hoạt trình duyệt bình thường gửi biểu mẫu Ext, hãy sử dụng tùy chọn cấu hình StandardSubmit.

Liên kết: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.Basic-cfg-standardSubmit

giải pháp: đặt standardSubmit: true trong cấu hình của bạn. Hy vọng rằng điều này sẽ giúp bạn :)


0

Tôi đã sử dụng điều này trong quá khứ, vì chúng tôi thường sử dụng cú pháp dao cạo để mã hóa

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

{

// thêm ẩn và biểu mẫu được nộp tại đây

}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.