2016-02-10 38 views
35

ho alcuni parametri che voglio postare forma codificata al mio server:Inserisci una domanda x-www-form-urlencoded da Reagire Native

{ 
    'userName': '[email protected]', 
    'password': 'Password!', 
    'grant_type': 'password' 
} 

sto inviando la mia richiesta (attualmente senza parametri) In questo modo

var obj = { 
    method: 'POST', 
    headers: { 
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 
    }, 
}; 
fetch('https://example.com/login', obj) 
    .then(function(res) { 
    // Do stuff with result 
    }); 

Come posso includere i parametri codificati in forma nella richiesta?

risposta

1

Per il caricamento di richieste POST codificate dal modulo, è consigliabile utilizzare l'oggetto FormData.

codice

Esempio:

var params = { 
    userName: '[email protected]', 
    password: 'Password!', 
    grant_type: 'password' 
}; 

var formData = new FormData(); 

for (var k in params) { 
    formData.append(k, params[k]); 
} 

var request = { 
    method: 'POST', 
    headers: headers, 
    body: formData 
}; 

fetch(url, request); 
+32

Questo non è application/x-www-form-urlencoded, ma multipart/form-data –

+0

Concordo, questa richiesta non avrà "application/x-www-form-urlencoded" come Content-Type ma "multipart/form -dati". – b4stien

+0

Che differenza farebbe quando si tratta del server che trova effettivamente le credenziali inviate? L'endpoint OAuth è progettato per accettare un tipo di contenuto e rifiutarne altri? – Mzn

1

Nell'esempio originale si dispone di una funzione transformRequest che converte un oggetto in Dati modulo codificati.

Nell'esempio revisionato l'avete sostituito con JSON.stringify che converte un oggetto in JSON.

In entrambi i casi si hanno 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' in modo che siano sostenendo di essere l'invio di dati forma codificata in entrambi i casi.

Utilizzare la funzione di codifica modulo anziché JSON.stringify.


Re aggiornamento:

Nella tua prima fetch ad esempio, è possibile impostare il body essere il valore JSON.

Ora è stata creata una versione codificata del modulo, ma invece di impostare il valore body, è stato creato un nuovo oggetto e impostato i dati del modulo codificati come proprietà di tale oggetto.

Non creare quell'oggetto aggiuntivo. Assegna il tuo valore a body.

+0

Ciao @Quentin. Ho semplicemente ridimensionato radicalmente la domanda per cercare di renderlo un riferimento più utile per i futuri lettori; così facendo, ho invalidato completamente la tua risposta che si riferisce ai dettagli e agli errori del codice originale del richiedente. Suppongo che tu abbia il diritto di annullare la mia modifica se vuoi, in teoria, non intendiamo apportare modifiche invalidanti per la risposta, che è quello che ho fatto, ma se vuoi essere disposto a farlo, penso che sia sarebbe meglio eliminare semplicemente questa risposta; IMO la domanda è molto più bella senza il codice angolare o il precedente tentativo fallito. –

91

Bisogna mettere insieme la x-www-form-urlencoded payload te, in questo modo:

var details = { 
    'userName': '[email protected]', 
    'password': 'Password!', 
    'grant_type': 'password' 
}; 

var formBody = []; 
for (var property in details) { 
    var encodedKey = encodeURIComponent(property); 
    var encodedValue = encodeURIComponent(details[property]); 
    formBody.push(encodedKey + "=" + encodedValue); 
} 
formBody = formBody.join("&"); 

fetch('https://example.com/login', { 
    method: 'POST', 
    headers: { 
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' 
    }, 
    body: formBody 
}) 

noti che se si stava utilizzando fetch in un browser (sufficientemente moderno), invece di React Native, potresti invece creare un oggetto URLSearchParams e utilizzarlo come corpo, dal momento che il Fetch Standard states che se il body è un URLSearchParams oggetto quindi dovrebbe essere serializzato come application/x-www-form-urlencoded. Tuttavia, non è possibile farlo in React Native perché React Native does not implement URLSearchParams.

+10

Questa è la vera risposta –

+16

Il modo ES6: 'const formBody = Object.keys (dettagli) .map (chiave => encodeURIComponent (chiave) + '=' + encodeURIComponent (dettagli [chiave])) join ('&');' –

+0

Questo polyfill per URLSearchParams https://github.com/WebReflection/url-search-params può funzionare per i browser React Native o precedenti. – bucabay

3

Usa URLSearchParams

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

var data = new URLSearchParams(); 
data.append('userName', '[email protected]'); 
data.append('password', 'Password'); 
data.append('grant_type', 'password'); 
+0

questo rende ciò che intendevo, dato che php7 non stava analizzando la codifica di FormData a destra. ottiene più voti per i ragazzi e le ragazze di PHP –

+0

-1; 'URLSearchParams' non esiste in React Native. (Vedi https://github.com/facebook/react-native/issues/9596.) –

-1

È possibile aggiungere una funzione di opporsi, in modo da poter serializzare un JSON più facile.

Object.prototype.serialize = function() { 
    if (!this) return; 

    var s = [] 

    for (var key in this) { 
    if (this.hasOwnProperty(key)) { 
     s.push(encodeURIComponent(key) + '=' + encodeURIComponent(this[key])) 
    } 
    } 

    return s.join('&') 
} 

Per utilizzare questo, devi solo scrivere semplicemente

obj.serialize() 

per esempio.

var data = { 
    a: 1, 
    b: 2, 
    c: true 
} 

fetch('/api_url', { 
    method: 'POST', 
    headers: { 
    'Accept': 'application/json', 
    'Content-Type': 'application/x-www-form-urlencoded' 
    }, 
    body: data.serialize() // see the usage here 
}) 
+1

-1; questa risposta è confusa: parli di JSON ma in realtà sono codifica di forma dell'oggetto.Inoltre, l'estensione di 'Object.prototype' è una cattiva pratica, dal momento che la tua estensione potrebbe entrare in conflitto con una proprietà con lo stesso nome definita da una libreria - o w orse, da una versione futura di ECMAScript stesso. –