AJAX POST i znak plus (+) - jak kodować?

98

Wysyłam zawartość pola formularza przez AJAX do skryptu PHP i używając JavaScript do escape(field_contents). Problem polega na tym, że wszelkie znaki plus są usuwane i zastępowane spacjami. Jak bezpiecznie „zakodować” znak plus, a następnie odpowiednio go „zdekodować” po stronie PHP?

jalperin
źródło
dla wyjaśnienia, użyłem ucieczki (field_contents), a nie kodowania
jalperin

Odpowiedzi:

156

Używając encodeURIComponent()w JS i PHP powinieneś otrzymać prawidłowe wartości.

Uwaga: Po uzyskaniu dostępu $_GET, $_POSTlub $_REQUESTw PHP, jesteś pobierania wartości, które zostały już odkodowane.

Przykład:

W twoim JS:

// url encode your string
var string = encodeURIComponent('+'); // "%2B"
// send it to your server
window.location = 'http://example.com/?string='+string; // http://example.com/?string=%2B

Na twoim serwerze:

echo $_GET['string']; // "+"

Tylko surowe żądanie HTTP zawiera dane zakodowane w postaci adresu URL.

W przypadku żądania GET możesz pobrać to z URI. $_SERVER['REQUEST_URI']lub $_SERVER['QUERY_STRING']. W przypadku POST z kodem urlencodfile_get_contents('php://stdin')

Uwaga:

decode()działa tylko dla znaków zakodowanych jednobajtowo. Nie będzie działać dla pełnego zakresu UTF-8.

na przykład:

text = "\u0100"; // Ā
// incorrect
escape(text); // %u0100 
// correct
encodeURIComponent(text); // "%C4%80"

Uwaga: "%C4%80"jest równoważne z:escape('\xc4\x80')

Jaka jest sekwencja bajtów ( \xc4\x80), która reprezentuje Āw UTF-8. Więc jeśli używasz encodeURIComponent()swojego serwera, musisz wiedzieć, że odbiera UTF-8. W przeciwnym razie PHP zmieni kodowanie.

bucabay
źródło
Jedna kontynuacja: kiedy koduję komponentURIComponent (tekst), a tekst zawiera znaki, takie jak inteligentny cytat (& rsqo;), skrypt php wydaje się widzieć niepotrzebne znaki. Zakładam, że jest to problem z kodowaniem znaków, ale nie wiem, jak go rozwiązać. Robię POST AJAX z "Content-Type": "application / x-www-form-urlencoded; charset = UTF-8" i używam PHP5 po stronie serwera.
jalperin
Jak oceniasz te postacie? Musisz się upewnić, że przeglądarka wie, że jest to UTF-8. W HTML możesz ustawić <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">lub <meta charset="UTF-8">możesz również ustawić go w PHP za pomocą nagłówka HTTP Content-Type. header('Content-Type: text/html;charset=UTF-8');PS: & rsqo; nie dekoduje w przeglądarce (FF3.5).
bucabay
5
Miałem problem ze zmianą znaku plus (+) w spację. Wszystko inne poszło dobrze w UTF8. Miałem szczęście używając encodeURIComponent (JSON.stringify (rootObject)). Dziękuję Ci!
zneo
Kiedy natknąłem się na ten problem z hasłami (które zostały zebrane za pośrednictwem postu formularza javascript) rozwiązałem go z hasłem = encodeURIComponent (hasło). Po przekazaniu do PHP zakodowana wartość hasła POST działa poprawnie.
lowcrawler
19

W JavaScript spróbuj:

encodeURIComponent() 

aw PHP:

urldecode($_POST['field']);
Deniss Kozlovs
źródło
7
encodeURIComponent jest właściwą odpowiedzią - ale ponieważ generuje dane zakodowane w adresie URL, a nie dane w formacie HTML, html_entity_encode jest zdecydowanie nie do pomyślenia.
Quentin
1
urldecodejest również daleko, ponieważ PHP zdekoduje go automatycznie przed wypełnieniem $_POST.
Quentin
5

Poszukiwana wartość szesnastkowa to %2B

Aby uzyskać to automatycznie w PHP, uruchom ciąg urlencode($stringVal). A potem uruchom to dobrzeurldecode($stringVal) aby go odzyskać.

Jeśli chcesz, aby JavaScript obsługiwał to, użyj escape( str )

Edytować

Po komentarzu @ bobince'a przeczytałem więcej i on ma rację. Użyj encodeURIComponent(str)i decodeURIComponent(str). Escape nie konwertuje znaków, a jedynie ucieka je za pomocą \'s

Rob Allen
źródło
1
Nie używaj escape(lub unescape) w JavaScript; nie są one tym samym, co kodowanie adresów URL i będą błędne dla znaków + i wszystkich znaków Unicode spoza ASCII. encodeURIComponent / decodeURIComponent jest prawie zawsze tym, czego chcesz.
bobince
4

Aby uczynić go bardziej interesującym i miejmy nadzieję, umożliwić mniejsze wyrywanie włosów komuś innemu. Używając Pythona, wbudowanego słownika dla urządzenia, które możemy skonfigurować za pomocą curl.

Problem: {"timezone":"+5"} //throws an error " 5"

Rozwiązanie: {"timezone":"%2B"+"5"} //Works

A więc w skrócie:

var = {"timezone":"%2B"+"5"}
json = JSONEncoder().encode(var)
subprocess.call(["curl",ipaddress,"-XPUT","-d","data="+json])

Dzięki temu wpisowi!

Pawr
źródło
0

Jeśli musisz zrobić curl w php, powinieneś używać urlencode()z PHP, ale indywidualnie!

strPOST = "Item1=" . $Value1 . "&Item2=" . urlencode("+")

Jeśli to zrobisz urlencode(strPOST), przyniesie ci kolejny problem, będziesz mieć jeden Item1 i & zmienisz wartość% xx i będzie to jedna wartość, zobacz tutaj wynik!

Przykład 1

$strPOST = "Item1=" . $Value1 . "&Item2=" . urlencode("+") will give Item1=Value1&Item2=%2B

Przykład 2

$strPOST = urlencode("Item1=" . $Value1 . "&Item2=+") will give Item1%3DValue1%26Item2%3D%2B

Przykład 1 to dobry sposób na przygotowanie ciągu do POST w curl

Przykład 2 pokazuje, że receptor nie zobaczy równości i znaku ampersand, aby rozróżnić obie wartości!

Marc
źródło
-1

mój problem dotyczył akcentów (á É ñ) i znaku plus (+), kiedy próbuję zapisać „przykłady kodu” javascript w mysql:

moje rozwiązanie (nie lepsze, ale działa):

javascript:

function replaceAll( text, busca, reemplaza ){
  while (text.toString().indexOf(busca) != -1)
  text = text.toString().replace(busca,reemplaza);return text;
}


function cleanCode(cod){
code = replaceAll(cod , "|", "{1}" ); // error | palos de explode en java
code = replaceAll(code, "+", "{0}" ); // error con los signos mas   
return code;
}

funkcja do zapisania:

function save(pid,code){
code = cleanCode(code); // fix sign + and |
code = escape(code); // fix accents
var url = 'editor.php';
var variables = 'op=save';
var myData = variables +'&code='+ code +'&pid='+ pid +'&newdate=' +(new Date()).getTime();    
var result = null;
$.ajax({
datatype : "html",
data: myData,  
url: url,
success : function(result) {
    alert(result); // result ok                     
},
}); 
} // end function

funkcja w php:

<?php
function save($pid,$code){
    $code= preg_replace("[\{1\}]","|",$code);
    $code= preg_replace("[\{0\}]","+",$code);
    mysql_query("update table set code= '" . mysql_real_escape_string($code) . "' where pid='$pid'");
}
?>
BX16Soupapes
źródło