Ich versuche, einen Browser auf eine andere Seite zu lenken. Wenn ich eine GET-Anfrage wollte, könnte ich sagen
document.location.href = 'http://example.com/q=a';
Die Ressource, auf die ich zugreifen möchte, reagiert jedoch nicht richtig, wenn ich nicht eine POST Anforderung verwende. Wenn dies nicht dynamisch generiert würde, könnte ich HTML verwenden
<form action="http://example.com/" method="POST">
<input type="hidden" name="q" value="a">
</form>
Dann würde ich einfach das Formular aus dem DOM einreichen.
Aber ich möchte wirklich JavaScript-Code, mit dem ich sagen kann
post_to_url('http://example.com/', {'q':'a'});
Was ist die beste Browserübergreifende Implementierung?
Bearbeiten
Es tut mir leid, dass ich nicht klar war. Ich brauche eine Lösung, die den Standort des Browsers ändert, genauso wie das Senden eines Formulars. Wenn dies mit XMLHttpRequest möglich ist, ist dies nicht offensichtlich. Dies sollte weder asynchron sein noch XML verwenden, daher ist Ajax nicht die Antwort.
/**
* 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();
}
Beispiel:
post('/contact/', {name: 'Johnny Bravo'});
EDIT: Da dies so viel zugesagt hat, schätze ich, dass die Leute dies oft kopieren. Also fügte ich die hasOwnProperty
-Prüfung hinzu, um unbeabsichtigte Fehler zu beheben.
Dies wäre eine Version der ausgewählten Antwort mit jQuery .
// Post to the provided URL with the specified parameters.
function post(path, parameters) {
var form = $('<form></form>');
form.attr("method", "post");
form.attr("action", path);
$.each(parameters, function(key, value) {
var field = $('<input></input>');
field.attr("type", "hidden");
field.attr("name", key);
field.attr("value", value);
form.append(field);
});
// The form needs to be a part of the document in
// order for us to be able to submit it.
$(document.body).append(form);
form.submit();
}
Eine einfache und schnelle Implementierung der @Aaron-Antwort:
document.body.innerHTML += '<form id="dynForm" action="http://example.com/" method="post"><input type="hidden" name="q" value="a"></form>';
document.getElementById("dynForm").submit();
Natürlich sollten Sie lieber ein JavaScript-Framework wie Prototype oder jQuery ... verwenden.
Verwenden der createElement
-Funktion, die in this answer zur Verfügung gestellt wird, was aufgrund der Brokenness von IE mit dem Namensattribut für Elemente erforderlich ist, die normalerweise mit document.createElement
erstellt wurden:
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);
}
Rakesh Pais Antwort ist erstaunlich, aber es gibt ein Problem, das für mich (in Safari ) auftritt, wenn ich versuche, ein Formular mit einem Feld namens submit
zu posten. Zum Beispiel post_to_url("http://google.com/",{ submit: "submit" } );
. Ich habe die Funktion etwas gepatcht, um diese variable Weltraumkollision zu umgehen.
function post_to_url(path, params, method) {
method = method || "post";
var form = document.createElement("form");
//Move the submit function to another variable
//so that it doesn't get overwritten.
form._submit_function_ = form.submit;
form.setAttribute("method", method);
form.setAttribute("action", path);
for(var key in params) {
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_function_(); //Call the renamed function.
}
post_to_url("http://google.com/", { submit: "submit" } ); //Works!
Nein, Sie können die JavaScript-Post-Anfrage nicht wie ein Formular einreichen.
Was Sie haben können, ist ein Formular in HTML, dann senden Sie es mit dem JavaScript. (wie schon oft auf dieser Seite erklärt)
Sie können den HTML-Code selbst erstellen, Sie benötigen kein JavaScript, um den HTML-Code zu schreiben. Das wäre dumm, wenn die Leute das vorschlagen würden.
<form id="ninja" action="http://example.com/" method="POST">
<input id="donaldduck" type="hidden" name="q" value="a">
</form>
Ihre Funktion würde das Formular einfach so konfigurieren, wie Sie es möchten.
function postToURL(a,b,c){
document.getElementById("ninja").action = a;
document.getElementById("donaldduck").name = b;
document.getElementById("donaldduck").value = c;
document.getElementById("ninja").submit();
}
Dann benutze es gerne.
postToURL("http://example.com/","q","a");
Aber ich würde die Funktion einfach weglassen und einfach tun.
document.getElementById('donaldduck').value = "a";
document.getElementById("ninja").submit();
Die Stilentscheidung wird schließlich in der ccs-Datei gespeichert.
.ninja{
display:none;
}
Ich persönlich denke, dass Formulare mit Namen angesprochen werden sollten, aber das ist im Moment nicht wichtig.
Wenn Sie Prototype installiert haben, können Sie den Code straffen, um das verborgene Formular zu generieren und zu senden:
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();
dies ist die Antwort von Rakesh, aber mit Unterstützung für Arrays (was in Formularen durchaus üblich ist):
einfaches Javascript:
function post_to_url(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);
var addField = function( key, value ){
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", value );
form.appendChild(hiddenField);
};
for(var key in params) {
if(params.hasOwnProperty(key)) {
if( params[key] instanceof Array ){
for(var i = 0; i < params[key].length; i++){
addField( key, params[key][i] )
}
}
else{
addField( key, params[key] );
}
}
}
document.body.appendChild(form);
form.submit();
}
oh, und hier ist die Jquery-Version: (etwas anderer Code, läuft aber auf dasselbe hinaus)
function post_to_url(path, params, method) {
method = method || "post"; // Set method to post by default, if not specified.
var form = $(document.createElement( "form" ))
.attr( {"method": method, "action": path} );
$.each( params, function(key,value){
$.each( value instanceof Array? value : [value], function(i,val){
$(document.createElement("input"))
.attr({ "type": "hidden", "name": key, "value": val })
.appendTo( form );
});
} );
form.appendTo( document.body ).submit();
}
Nun, ich wünschte, ich hätte alle anderen Beiträge gelesen, damit ich keine Zeit verliere, indem ich die Antwort von Rakesh Pai erstellte. Hier ist eine rekursive Lösung, die mit Arrays und Objekten arbeitet. Keine Abhängigkeit von jQuery.
Es wurde ein Segment hinzugefügt, um Fälle zu behandeln, bei denen das gesamte Formular wie ein Array übermittelt werden soll. (dh wo kein Wrapper-Objekt um eine Liste von Elementen ist)
/**
* 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();
};
Eine Lösung besteht darin, das Formular zu generieren und abzusenden. Eine Implementierung ist
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();
}
So kann ich ein URL-verkürzendes Bookmarklet mit einem einfachen implementieren
javascript:post_to_url('http://is.Gd/create.php', {'URL': location.href});
Drei Möglichkeiten hier.
Standard JavaScript Antwort: Verwenden Sie ein Framework! Die meisten Ajax-Frameworks haben Ihnen eine einfache Möglichkeit geboten, einen XMLHTTPRequest POST zu erstellen.
Stellen Sie die XMLHTTPRequest-Anforderung selbst her, und übergeben Sie die Post an die open-Methode, anstatt sie zu erhalten. (Weitere Informationen finden Sie in Verwenden der POST - Methode in XMLHTTPRequest (Ajax).)
Erstellen Sie über JavaScript dynamisch ein Formular, fügen Sie eine Aktion hinzu, fügen Sie Ihre Eingaben hinzu und übergeben Sie diese.
So habe ich es mit jQuery geschrieben. Getestet in Firefox und Internet Explorer.
function postToUrl(url, params, newWindow) {
var form = $('<form>');
form.attr('action', url);
form.attr('method', 'POST');
if(newWindow){ form.attr('target', '_blank');
}
var addParam = function(paramName, paramValue) {
var input = $('<input type="hidden">');
input.attr({ 'id': paramName,
'name': paramName,
'value': paramValue });
form.append(input);
};
// Params is an Array.
if(params instanceof Array){
for(var i=0; i<params.length; i++) {
addParam(i, params[i]);
}
}
// Params is an Associative array or Object.
if(params instanceof Object) {
for(var key in params){
addParam(key, params[key]);
}
}
// Submit the form, then remove it from the page
form.appendTo(document.body);
form.submit();
form.remove();
}
Ich würde die Ajax-Route hinuntergehen, wie andere vorgeschlagen haben:
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open("POST", "YourPageHere.asp", true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
self.xmlHttpReq.setRequestHeader("Content-length", QueryString.length);
self.xmlHttpReq.send("?YourQueryString=Value");
Der einfachste Weg ist die Verwendung von Ajax Post Request:
$.ajax({
type: "POST",
url: 'http://www.myrestserver.com/api',
data: data,
success: success,
dataType: dataType
});
woher:
Dann leiten Sie im Erfolgs-Handler den Browser mit etwas wie window.location um.
Die Prototype - Bibliothek enthält ein Hashtable-Objekt mit der Methode ".toQueryString ()", mit der Sie ein JavaScript-Objekt/eine JavaScript-Struktur leicht in eine Abfragezeichenfolge-Zeichenfolge umwandeln können. Da der Beitrag erfordert, dass der "Hauptteil" der Anforderung eine aus einer Abfragezeichenfolge formatierte Zeichenfolge ist, kann Ihre Ajax-Anforderung als Beitrag ordnungsgemäß funktionieren. Hier ist ein Beispiel mit 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();
};
Das funktioniert in meinem Fall perfekt:
document.getElementById("form1").submit();
Sie können es in der Funktion wie verwenden:
function formSubmit() {
document.getElementById("frmUserList").submit();
}
Damit können Sie alle Werte der Eingaben buchen.
Im Gegensatz zu der derzeit von @RakeshPai akzeptierten Lösung wird meine Lösung tief verschachtelte Objekte kodieren.
Es verwendet die 'qs' npm-Bibliothek und ihre Funktion stringify, um verschachtelte Objekte in Parameter zu konvertieren.
Dieser Code funktioniert gut mit einem Rails-Backend, obwohl Sie in der Lage sein sollten, ihn mit dem von Ihnen benötigten Backend zu modifizieren, indem Sie die Optionen ändern, die an stringify übergeben werden. Rails erfordert, dass arrayFormat auf "Klammern" gesetzt ist.
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();
}
Beispiel:
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"]
}
]
});
Produziert diese Rails-Parameter:
{"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"]}]}
Noch eine andere rekursive Lösung, da einige andere als defekt erscheinen (ich habe nicht alle getestet). Diese hängt von lodash 3.x und ES6 ab (jQuery nicht erforderlich):
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();
}
Sie können das Formular mithilfe von DHTML dynamisch hinzufügen und anschließend senden.
Sie könnten eine Bibliothek wie jQuery und ihre $ .post-Methode verwenden.
Ich verwende die document.forms Java und verwende eine Schleife, um alle Elemente im Formular zu erhalten, und sende dann über xhttp. Das ist also meine Lösung für Javascript/Ajax-Submit (mit allen HTML-Dateien als Beispiel):
<!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>
Dies basiert auf dem Code von beauSD, der jQuery verwendet. Es wurde verbessert, sodass es bei Objekten rekursiv funktioniert.
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();
}
Dies ist wie bei Option 2 von Alan (oben). Wie man das httpobj instanziiert, bleibt als Übung übrig.
httpobj.open("POST", url, true);
httpobj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
httpobj.onreadystatechange=handler;
httpobj.send(post);
FormObject ist eine Option. FormObject wird derzeit jedoch von den meisten Browsern nicht unterstützt.
Die Methode, mit der ich einen Benutzer automatisch poste und auf eine andere Seite weiterleitet, besteht darin, einfach ein verstecktes Formular zu schreiben und es dann automatisch zu senden. Seien Sie versichert, dass das versteckte Formular auf der Webseite absolut keinen Platz einnimmt. Der Code würde ungefähr so aussehen:
<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();
Anwendung von Auto Submit
Eine Anwendung der automatischen Übermittlung würde Formularwerte, die der Benutzer automatisch auf der anderen Seite eingibt, auf diese Seite umleiten. Eine solche Anwendung wäre so:
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();
}
So mache ich es.
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();
}
jQuery-Plugin zur Weiterleitung mit POST oder GET:
https://github.com/mgalante/jquery.redirect/blob/master/jquery.redirect.js
Um dies zu testen, schließen Sie die obige .js-Datei ein oder kopieren/fügen Sie die Klasse in Ihren Code ein. Verwenden Sie dann den Code hier und ersetzen Sie "args" durch Ihre Variablennamen und "values" durch die Werte dieser Variablen:
$.redirect('demo.php', {'arg1': 'value1', 'arg2': 'value2'});
Sie könnten die jQuery-Triggermethode zum Senden des Formulars verwenden, genau wie Sie eine Schaltfläche drücken.
$('form').trigger('submit')
es wird im Browser eingereicht.