Niech link używa POST zamiast GET

204

Nie jestem pewien, czy to w ogóle możliwe. Zastanawiałem się jednak, czy ktokolwiek wie, jak sprawić, by hiperłącze przechodziło przez niektóre zmienne i używało POST (jak formularz) zamiast GET.

Elliot
źródło
HTML nie może tego zrobić. JavaScript może wychwycić zdarzenie kliknięcia na link i zrobić, co chcesz, jeśli nie możesz zmienić HTML, a CSS może stylizować przycisk podobny do linku, jeśli to tylko kwestia wyglądu.
sylvain,

Odpowiedzi:

98

Tworzysz formularz z ukrytymi danymi wejściowymi, które przechowują wartości do opublikowania, ustawiasz działanie formularza na docelowy adres URL i metodę formularza do opublikowania . Następnie po kliknięciu linku uruchom funkcję JS, która przesyła formularz.

Zobacz tutaj przykład. W tym przykładzie użyto czystego JavaScript bez jQuery - możesz to wybrać, jeśli nie chcesz instalować niczego więcej niż już masz.

<form name="myform" action="handle-data.php" method="post">
  <label for="query">Search:</label>
  <input type="text" name="query" id="query"/>
  <button>Search</button>
</form>

<script>
var button = document.querySelector('form[name="myform"] > button');
button.addEventListener(function() {
  document.querySelector("form[name="myform"]").submit();
});
</script>
Palantir
źródło
16
Dlaczego jest to akceptowana odpowiedź? Pytanie dotyczy w szczególności użycia POST (jak formularza) w przeciwieństwie do GET , ale ta odpowiedź mówi „ ustaw akcję na docelowy adres URL i metodę uzyskania ”.
Majid Fouladpour
3
Rozumiem. Nie rozumiem tego: mamy problem z utworzeniem ukrytej formy, abyśmy mogli POST, ale potem, po utworzeniu formularza, dlaczego proponujesz ustawić metodę GET? Mieliśmy getbez formularza, prawda?
Majid Fouladpour
3
Masz rację. To był błąd, ale w jakiś sposób OP nadal go poprawił (prawdopodobnie ze względu na dołączony link, który jest znacznie wyraźniejszy). Dzięki za wskazanie. Całkowicie to sformułowałem.
Palantir,
3
Zaktualizowałem twoją odpowiedź, aby zastosować bardziej nowoczesne podejście. Jeśli się nie zgadzasz, możesz cofnąć tę edycję.
Michał Perłakowski
3
Nie ma powodu, aby włączać Javascript w ten proces. Dlaczego jest to akceptowana odpowiedź?
shacker
322

Nie potrzebujesz do tego JavaScript. Chciałem tylko to wyjaśnić, ponieważ od momentu opublikowania tej odpowiedzi wszystkie odpowiedzi na to pytanie wymagają użycia JavaScript w taki czy inny sposób.

Możesz to zrobić dość łatwo za pomocą czystego HTML i CSS , tworząc formularz z ukrytymi polami zawierającymi dane, które chcesz przesłać, a następnie stylizując przycisk wysyłania formularza, aby wyglądał jak link.

Na przykład:

.inline {
  display: inline;
}

.link-button {
  background: none;
  border: none;
  color: blue;
  text-decoration: underline;
  cursor: pointer;
  font-size: 1em;
  font-family: serif;
}
.link-button:focus {
  outline: none;
}
.link-button:active {
  color:red;
}
<a href="some_page">This is a regular link</a>

<form method="post" action="some_page" class="inline">
  <input type="hidden" name="extra_submit_param" value="extra_submit_value">
  <button type="submit" name="submit_param" value="submit_value" class="link-button">
    This is a link that sends a POST request
  </button>
</form>

Dokładny styl CSS może się różnić w zależności od stylu regularnych linków w witrynie.

Ajedi32
źródło
4
Zgoda. Potrzebowałem sposobu na zrobienie tego w wiadomości e-mail, więc JS nie była dla mnie zbyt dużą opcją. To powinno działać idealnie
SynackSA
7
Mogę to zagłosować tylko raz. Jest to prawie tak smutne, jak fakt, że 99,728% wszystkich pytań HTML zostanie pomylonych z problemami JavaScript lub jQuery.
Rab
3
Jest to z pewnością prosty sposób na użycie przycisku, który wygląda jak link, ale tak naprawdę jest on mocno zakodowany. Musisz dokładnie poznać warunki, w jakich będzie żyć ten przycisk i ustawić je wyraźnie dla każdego przypadku. Myślę, że odpowiedzi oparte na JS / JQuery są bardziej ogólne, ponieważ korzystają z samego elementu link (lub dowolnego innego elementu).
MakisH,
2
@ Ajedi32 Przepraszam, mój komentarz nie był tak jasny: staram się głównie powiedzieć, że ten przycisk jest zaprojektowany tak, aby wyglądał jak element <a>. Ale jeśli umieścisz przycisk wokół innych elementów <a>, które są inaczej stylizowane, np. W różnych częściach strony, musisz zduplikować wszystkie reguły css <a> również dla przycisku, aby utworzyć reguły dla aktywowania, odwiedzania itp. W przeciwnym razie oczywiście wykona zadanie, ale będzie wyglądać brzydko. W przypadku innych rozwiązań po prostu nie musisz zmieniać żadnego CSS, po prostu dostajesz element <a>, jak wszystkie inne, które już masz. Oczywiście czysty HTML ma również pewne zalety.
MakisH
1
@Robert AFAIK, żadne z innych proponowanych rozwiązań nie działa z kliknięciem środkowym przyciskiem. Jeśli naprawdę chcesz być pedantyczny, możesz powiedzieć, że przesłanie żądania POST z linkiem jest niemożliwe. Możesz przesyłać żądania POST tylko za pomocą formularzy i JavaScript.
Ajedi32
48

Możesz użyć funkcji javascript. JQuery ma wbudowaną ładną funkcję post, jeśli zdecydujesz się jej użyć:

JQuery Post

<script language="javascript"> 

   function DoPost(){
      $.post("WhateverPage.php", { name: "John", time: "2pm" } );  //Your values here..
   }

</script>


<a href="javascript:DoPost()">Click Here</A> 
AGoodDisplayName
źródło
5
To powoduje, że żądanie POST jest zadawane, ale nie mogłem tego użyć, ponieważ nadal muszę udać się do lokalizacji „Whthing.php”.
Chris
6
$.post('page.php', {param: 1}, function() { window.location.href = 'page'.php' });
JREAM
1
@mplungjan href mówi, do kogo prowadzi odnośnik, a ja zgadzam się, że mylne jest zachowanie i treść, w tym przypadku javascript jest odniesieniem. Innymi słowy „kliknięcie linku spowoduje odesłanie zwrotne za pomocą JavaScript”. Ma to większe znaczenie niż wiązanie zdarzenia kliknięcia. Twarde zasady, takie jak „nigdy nie używaj javascript w href” są tak samo złe, jak każda inna zła praktyka.
Menol
@Menol Powiedziałem: nie zalecane. - nie „nigdy nie używaj”. Jeśli naprawdę chcesz, możesz to zrobić <a href="whyjavascript.html" id="postIt">Click Here</a>i mieć$("#postIt").on("click",function(e) { e.preventDefault(); $.post("WhateverPage.php", { name: "John", time: "2pm" } ); });
mplungjan,
1
@mplungjan to zalecenie, jak każde inne, wprowadzono, aby uniknąć mylących treści / zachowania. Kiedy zalecenie jest przedstawiane w przypadkach poza jego zamierzonym zakresem, zaczyna pojawiać się jako twarda reguła. Podany przykład wydaje się być o krok dalej, aby być po bezpiecznej stronie „reguły”, aby nikt nie mógł obwiniać programisty w przyszłości, ale to bezpieczeństwo jest osiągane kosztem czytelności i znaczenia. Tak wygląda inny pragmatyczny programista, ale jestem pewien, że nie miałeś tego na myśli.
Menol
24

To jest stare pytanie, ale żadna z odpowiedzi nie spełnia pełnego żądania. Więc dodaję inną odpowiedź.

Żądany kod, jak rozumiem, powinien wprowadzić tylko jedną zmianę w działaniu normalnych hiperłączy: POSTzamiast tego należy użyć metody GET. Bezpośrednie implikacje byłyby następujące:

  1. Po kliknięciu linku powinniśmy ponownie załadować kartę do adresu URL href
  2. Ponieważ metodą jest POST, nie powinniśmy mieć ciągu zapytania w adresie URL ładowanej strony docelowej
  3. Ta strona powinna otrzymać dane w parametrach (nazwach i wartości) do POST

Używam tutaj jquery, ale można to zrobić za pomocą natywnych apis (trudniejsze i dłuższe oczywiście).

<html>
<head>
    <script src="path/to/jquery.min.js" type="text/javascript"></script>
    <script>
        $(document).ready(function() {

            $("a.post").click(function(e) {
                e.stopPropagation();
                e.preventDefault();
                var href = this.href;
                var parts = href.split('?');
                var url = parts[0];
                var params = parts[1].split('&');
                var pp, inputs = '';
                for(var i = 0, n = params.length; i < n; i++) {
                    pp = params[i].split('=');
                    inputs += '<input type="hidden" name="' + pp[0] + '" value="' + pp[1] + '" />';
                }
                $("body").append('<form action="'+url+'" method="post" id="poster">'+inputs+'</form>');
                $("#poster").submit();
            });
        });
    </script>
</head>
<body>
    <a class="post" href="reflector.php?color=blue&weight=340&model=x-12&price=14.800">Post it!</a><br/>
    <a href="reflector.php?color=blue&weight=340&model=x-12&price=14.800">Normal link</a>
</body>
</html>

Aby zobaczyć wynik, zapisz następujące jako reflector.php w tym samym katalogu, w którym zapisałeś powyższe.

<h2>Get</h2>
<pre>
<?php print_r($_GET); ?>
</pre>

<h2>Post</h2>
<pre>
<?php print_r($_POST); ?>
</pre>
Majid Fouladpour
źródło
12

Kolejny działający przykład, wykorzystujący podobne podejście: stwórz formularz HTML, użyj javascript do symulacji postu. Robi to 2 rzeczy: publikuje dane na nowej stronie i otwiera je w nowym oknie / karcie.

HTML

<form name='myForm' target="_blank" action='newpage.html' method='post'>
<input type="hidden" name="thisIsTheParameterName" value="testDataToBePosted"/>
</form>

JavaScript

document.forms["myForm"].submit();
Quannt
źródło
3

HTML + JQuery : link, który przesyła ukryty formularz za pomocą POST.

Ponieważ spędziłem dużo czasu na zrozumieniu wszystkich tych odpowiedzi, a ponieważ wszystkie mają kilka interesujących szczegółów, oto wersja łączona, która w końcu działała dla mnie i którą preferuję ze względu na jej prostotę.

Moje podejście polega na utworzeniu ukrytego formularza i przesłaniu go poprzez kliknięcie łącza w innym miejscu na stronie. Nie ma znaczenia, gdzie w treści strony zostanie umieszczony formularz.

Kod formularza:

<form id="myHiddenFormId" action="myAction.php" method="post" style="display: none">
  <input type="hidden" name="myParameterName" value="myParameterValue">
</form>

Opis:

display: noneUkrywa formularza. Możesz alternatywnie umieścić go w div lub innym elemencie i ustawić display: nonena elemencie.

type="hidden"Stworzy fild że nie będą wyświetlane, ale jego dane zostaną przekazane do eitherways działania ( patrz W3C ). Rozumiem, że jest to najprostszy typ danych wejściowych.

Kod linku:

<a href="" onclick="$('#myHiddenFormId').submit(); return false;" title="My link title">My link text</a>

Opis:

Pusty hrefjest kierowany tylko na tę samą stronę . Ale tak naprawdę nie ma to znaczenia w tym przypadku, ponieważ return falsepowstrzyma przeglądarkę przed podążaniem za linkiem. Oczywiście możesz zmienić to zachowanie. W moim konkretnym przypadku akcja zawierała przekierowanie na końcu.

onclickUżyto unikać stosowania href="javascript:..."jako zauważył mplungjan . $('#myHiddenFormId').submit();Użyto do złożenia formularza (zamiast definiowania funkcji, ponieważ kod jest bardzo małe).

Ten link będzie wyglądał dokładnie tak, jak każdy inny <a>element. Możesz użyć dowolnego innego elementu zamiast <a>(na przykład a <span>lub obrazu).

MakisH
źródło
2

Możesz użyć tej funkcji jQuery

function makePostRequest(url, data) {
    var jForm = $('<form></form>');
    jForm.attr('action', url);
    jForm.attr('method', 'post');
    for (name in data) {
        var jInput = $("<input>");
        jInput.attr('name', name);
        jInput.attr('value', data[name]);
        jForm.append(jInput);
    }
    jForm.submit();
}

Oto przykład w jsFiddle ( http://jsfiddle.net/S7zUm/ )

DarkThanos
źródło
@ExeLam kod faktycznie działa. I podstawiony leserged.free.fr/phpinfo.php dla wartości w phpref i pisał formularz do tej witryny przechodzącej w wartościach.
JSWilson
2

Jak wspomniano w wielu postach, nie jest to bezpośrednio możliwe, ale prosty i skuteczny sposób jest następujący: Po pierwsze, umieszczamy formularz w treści naszej strony HTML, która nie zawiera żadnych przycisków do przesyłania, a także danych wejściowych są ukryte Następnie używamy funkcji javascript, aby uzyskać dane i wysłać formularz. Jedną z zalet tej metody jest przekierowanie na inne strony, które zależą od kodu po stronie serwera. Kod jest następujący: a teraz gdziekolwiek potrzebujesz być w metodzie „POST”:

<script type="text/javascript" language="javascript">
function post_link(data){

    $('#post_form').find('#form_input').val(data);
    $('#post_form').submit();
};
</script>

   <form id="post_form" action="anywhere/you/want/" method="POST">
 {% csrf_token %}
    <input id="form_input" type="hidden" value="" name="form_input">
</form>

<a href="javascript:{}" onclick="javascript:post_link('data');">post link is ready</a>
Mahdi Firouzjah
źródło
1

Sugeruję bardziej dynamiczne podejście, bez kodowania HTML na stronie, zachowaj to ściśle JS:

$("a.AS-POST").on('click', e => {
  e.preventDefault()
  let frm = document.createElement('FORM')
  frm.id='frm_'+Math.random()
  frm.method='POST'
  frm.action=e.target.href
  document.body.appendChild(frm)
  frm.submit()
})
Nimrod
źródło
0

Zamiast używać javascript, możesz również użyć etykiety wysyłającej ukryty formularz. Bardzo proste i małe rozwiązanie. Etykieta może znajdować się w dowolnym miejscu w html.

<form style="display: none" action="postUrl" method="post">
  <button type="submit" id="button_to_link"> </button>
</form>
<label style="text-decoration: underline" for="button_to_link">  link that posts </label>

Gladhon
źródło
-1

Sprawdź, to ci pomoże

$().redirect('test.php', {'a': 'value1', 'b': 'value2'});
Shoaib Quraishi
źródło
2
Należy wspomnieć, że to rozwiązanie wymaga następującej biblioteki: github.com/mgalante/jquery.redirect
Felix G.