2010-01-04 9 views
12

Para una petición GET He probado este método simple:¿Cómo se inserta una solicitud POST en un UIWebView

 NSString *urlAddress = @"http://example.com/"; 
     NSURL *url = [NSURL URLWithString:urlAddress]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
     [uiWebViewThingy loadRequest:request]; 

(Aunque no parece funcionar si la solicitud contiene caracteres de alta UTF-8 .)

Deseo enviar una POST desde el iPhone.

Esto también da una visión general para sending POST/GET requests aunque lo que realmente quiero hacer es incrustar la página web resultante en UIWebView. ¿Cuál sería la mejor manera de sortear eso?

Respuesta

12

Puede usar una NSMutableURLRequest, establecer el método HTTP en POST y luego cargarlo en su UIWebView usando -loadRequest.

+0

Esto es mejor. –

+0

Esto es lo que probé (ver el enlace en el OP) y traté de usar el método connectionDidFinishLoading para hacer algo como [uiWebViewThing loadRequest: responseData] pero es el tipo de datos incorrecto. Los datos de respuesta son NSMutable pero deben ser NSUrlRequest; debo estar haciendo algo obvio equivocado. – Gazzer

+1

El código anterior usa una solicitud NSURL. Necesita usar una NSMutableURLRequest. No te metas con connectionDidFinishLoading, simplemente cárgalo en webView usando -loadRequest. –

2

Usando loadHTMLString, pase una página al UIWebView que tiene un formulario oculto, rellenado previamente, luego haga que la página haga un formulario de Javascript [0] .submit() al cargar.

EDITAR: Primero, se recopila la entrada en las variables. Luego de componer HTML así:

NSMutableString *s = [NSMutableString stringWithCapacity:0]; 
[s appendString: @"<html><body onload=\"document.forms[0].submit()\">" 
"<form method=\"post\" action=\"http://someplace.com/\">" 
"<input type=\"hidden\" name=\"param1\">"]; 
[s appendString: Param1Value]; //It's your variable 
[s appendString: @"</input></form></body></html>"]; 

Luego se agrega a la vista Web:

[myWebView loadHTMLString:s baseURL:nil]; 

Esto hará que el WebView cargar el formulario, a continuación, presentar inmediatamente, ejecutando así una petición POST a un sitio .com (su URL variará). El resultado aparecerá en WebView.

Los detalles de la forma dependen de usted ...

+0

Realmente no entiendo esto. Estoy tratando de enviar una solicitud POST desde el iPhone en función de la entrada de un usuario y hacer que el servidor produzca una página que a su vez aparecerá dentro de UIWebView. – Gazzer

+0

Esto también es cierto para 'WKWebView' (iOS8). Porque tal vez hay un error y también funciona el método 'loadHTMLString' – Aznix

3

Usted puede usar algo como ASIHTTPRequest para hacer la solicitud POST (Con la opción de hacerlo de forma asíncrona) y luego cargar la cadena de respuesta/datos en el UIWebView. Consulte this page en la sección titulada Enviar datos con solicitudes POST o PUT y luego consulte Creación de una solicitud asincrónica sección en la parte superior para obtener información sobre cómo manejar la cadena/datos de respuesta.

Espero que ayude, lo siento si malinterpreté su pregunta.

+0

¿Cómo cargaría la cadena de respuesta de una ASIHttpRequest en UIWebView? – MikeN

+0

@MikeN, '- (void) loadHTMLString: (NSString *) string baseURL: (NSURL *) baseURL' –

9

Gracias por su respuesta Seva. He hecho un método fuera de su código, espero que esto ayuda a otras personas :)

//------------------------------------------------------------------- 
// UIWebViewWithPost 
//  init a UIWebview With some post parameters 
//------------------------------------------------------------------- 
- (void)UIWebViewWithPost:(UIWebView *)uiWebView url:(NSString *)url params:(NSMutableArray *)params 
{ 
    NSMutableString *s = [NSMutableString stringWithCapacity:0]; 
    [s appendString: [NSString stringWithFormat:@"<html><body onload=\"document.forms[0].submit()\">" 
    "<form method=\"post\" action=\"%@\">", url]]; 
    if([params count] % 2 == 1) { NSLog(@"UIWebViewWithPost error: params don't seem right"); return; } 
    for (int i=0; i < [params count]/2; i++) { 
     [s appendString: [NSString stringWithFormat:@"<input type=\"hidden\" name=\"%@\" value=\"%@\" >\n", [params objectAtIndex:i*2], [params objectAtIndex:(i*2)+1]]]; 
    }  
    [s appendString: @"</input></form></body></html>"]; 
    //NSLog(@"%@", s); 
    [uiWebView loadHTMLString:s baseURL:nil]; 
} 

utilizarlo

NSMutableArray *webViewParams = [NSMutableArray arrayWithObjects: 
           @"paramName1", @"paramValue1", 
           @"paramName2", @"paramValue2", 
           @"paramName3", @"paramValue3", 
           nil]; 
[self UIWebViewWithPost:self.webView url:@"http://www.yourdomain.com" params:webViewParams]; 
+0

Esto resolvió mi problema, muchas gracias. Quiero mejorar la respuesta, puede usar Dictionary en lugar de Array para evitar perder el par clave-valor. Usar este código de ejemplo: 'para (NSString * clave en params) { NSString * hiddenParam = [NSString stringWithFormat: @ " \ n ", clave, [params objectForKey: clave]]; [s appendString: hiddenParam]; } ' – krischu

5

(respuesta original editado para incluir código recién probado)

Solo quería agregar mi versión de esta solicitud. He usado un diccionario para representar los parámetros de la publicación.

Es un trozo de código, pero es lo suficientemente simple como para aparecer en una vista con una vista web y usar para todas las URL de carga. Solo PUBLICARÁ si envía un mensaje "PostDiccionario". De lo contrario, usará la url que le enviaste para OBTENER cosas.

- (void) loadWebView:(UIWebView *)theWebView withURLString:(NSString *)urlString andPostDictionaryOrNil:(NSDictionary *)postDictionary { 
    NSURL *url       = [NSURL URLWithString:urlString]; 
    NSMutableURLRequest *request  = [NSMutableURLRequest requestWithURL:url 
              cachePolicy:NSURLRequestReloadIgnoringCacheData 
             timeoutInterval:60.0]; 


    // DATA TO POST 
    if(postDictionary) { 
     NSString *postString    = [self getFormDataString:postDictionary]; 
     NSData *postData     = [postString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 
     NSString *postLength    = [NSString stringWithFormat:@"%d", [postData length]]; 
     [request setHTTPMethod:@"POST"]; 
     [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
     [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
     [request setHTTPBody:postData]; 
    } 

    [theWebView loadRequest:request]; 
} 
- (NSString *)getFormDataString:(NSDictionary*)dictionary { 
    if(! dictionary) { 
     return nil; 
    } 
    NSArray* keys        = [dictionary allKeys]; 
    NSMutableString* resultString    = [[NSMutableString alloc] init]; 
    for (int i = 0; i < [keys count]; i++) { 
     NSString *key       = [NSString stringWithFormat:@"%@", [keys objectAtIndex: i]]; 
     NSString *value       = [NSString stringWithFormat:@"%@", [dictionary valueForKey: [keys objectAtIndex: i]]]; 

     NSString *encodedKey     = [self escapeString:key]; 
     NSString *encodedValue     = [self escapeString:value]; 

     NSString *kvPair      = [NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue]; 
     if(i > 0) { 
      [resultString appendString:@"&"]; 
     } 
     [resultString appendString:kvPair]; 
    } 
    return resultString; 
} 
- (NSString *)escapeString:(NSString *)string { 
    if(string == nil || [string isEqualToString:@""]) { 
     return @""; 
    } 
    NSString *outString  = [NSString stringWithString:string]; 
    outString     = [outString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

    // BUG IN stringByAddingPercentEscapesUsingEncoding 
    // WE NEED TO DO several OURSELVES 
    outString     = [self replace:outString lookFor:@"&" replaceWith:@"%26"]; 
    outString     = [self replace:outString lookFor:@"?" replaceWith:@"%3F"]; 
    outString     = [self replace:outString lookFor:@"=" replaceWith:@"%3D"]; 
    outString     = [self replace:outString lookFor:@"+" replaceWith:@"%2B"]; 
    outString     = [self replace:outString lookFor:@";" replaceWith:@"%3B"]; 

    return outString; 
} 
- (NSString *)replace:(NSString *)originalString lookFor:(NSString *)find replaceWith:(NSString *)replaceWith { 
    if (! originalString || ! find) { 
     return originalString; 
    } 

    if(! replaceWith) { 
     replaceWith     = @""; 
    } 

    NSMutableString *mstring  = [NSMutableString stringWithString:originalString]; 
    NSRange wholeShebang   = NSMakeRange(0, [originalString length]); 

    [mstring replaceOccurrencesOfString: find 
          withString: replaceWith 
           options: 0 
            range: wholeShebang]; 

    return [NSString stringWithString: mstring]; 
} 
0

Crear POSTAL URLRequest y lo utilizan para llenar web View

NSURL *url = [NSURL URLWithString: @"http://your_url.com"]; 
NSString *body = [NSString stringWithFormat: @"arg1=%@&arg2=%@", @"val1",@"val2"]; 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url]; 
[request setHTTPMethod: @"POST"]; 
[request setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]]; 
[webView loadRequest: request]; 
0

He aquí una versión Swift de la respuesta de Seva Alekseyev que funcionaba perfectamente para mí. Gracias por el buen compañero de correo! Por cierto, el código siguiente está en Swift 3.1.

fileprivate func prepareDataAndSubmitForRepayment(parameters paramData: [String: Any]) { 
    var stringObj = String() 
    stringObj.append("<html><head></head>") 
    stringObj.append("<body onload=\"payment_form.submit()\">") 
    stringObj.append("<form id=\"payment_form\" action=\"\(urlString)\" method=\"post\">") //urlString is your server api string! 

    for object in paramData { //Extracting the parameters for request 
     stringObj.append("<input name=\"\(object.key)\" type=\"hidden\" value=\"\(object.value)\">") 
    } 

    stringObj.append("</form></body></html>") 
    debugPrint(stringObj) 
    webviewToLoadPage?.loadHTMLString(stringObj, baseURL: nil) 
} 
Cuestiones relacionadas