iPhone 上的 JSON POST 请求(使用 HTTPS)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4085978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:38:22  来源:igfitidea点击:

JSON POST Request on the iPhone (Using HTTPS)

iphoneobjective-cjsonsslhttps

提问by ingh.am

I have a WCF service hosted and I'm trying to use it within an iPhone app as a JSON POST request. I plan on using the JSON serializer later, but this is what I have for the request:

我有一个 WCF 服务托管,我试图在 iPhone 应用程序中使用它作为 JSON POST 请求。我计划稍后使用 JSON 序列化程序,但这就是我的请求:

    NSString *jsonRequest = @"{\"username\":\"user\",\"password\":\"letmein\"}";
    NSLog(@"Request: %@", jsonRequest);

    NSURL *url = [NSURL URLWithString:@"https://mydomain.com/Method/"];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody: requestData];

    [NSURLConnection connectionWithRequest:[request autorelease] delegate:self];

In my data received I'm just printing it to the console:

在我收到的数据中,我只是将其打印到控制台:

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSMutableData *d = [[NSMutableData data] retain];
    [d appendData:data];

    NSString *a = [[NSString alloc] initWithData:d encoding:NSASCIIStringEncoding];

    NSLog(@"Data: %@", a);
}

And within this response I get this message:

在这个回复中,我收到了这条消息:

Data: ???<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Request Error</title>
    <style>
        <!-- I've took this out as there's lots of it and it's not relevant! -->
    </style>
  </head>
  <body>
    <div id="content">
      <p class="heading1">Request Error</p>
      <p xmlns="">The server encountered an error processing the request. Please see the <a rel="help-page" href="https://mydomain.com/Method/help">service help page</a> for constructing valid requests to the service.</p>
    </div>
  </body>
</html>

Does anyone know why this happens and where I'm going wrong?

有谁知道为什么会发生这种情况以及我哪里出错了?

I've read about using ASIHTTPPostinstead but I can't get the demo to run in iOS4 :(

我读过有关使用ASIHTTPPost 的信息,但我无法在 iOS4 中运行演示 :(

Thanks

谢谢

EDIT:

编辑:

I've just used to CharlesProxyto sniff out what's happening when I call from the iPhone (Simulator) and this is what it gave me: alt text

我刚刚使用CharlesProxy来嗅探从 iPhone(模拟器)调用时发生的事情,这就是它给我的: 替代文字

The only thing strange I've noticed is it says "SSL Proxying not enabled for this host: enable in Proxy Settings, SSL locations". Does anyone know what this means?(This also happens in my working windows client).

我注意到的唯一奇怪的是它说“未为此主机启用 SSL 代理:在代理设置、SSL 位置中启用”。有谁知道这是什么意思?(这也发生在我工作的 Windows 客户端中)。

I've just ran this on my windows client and the only thing that is different is the Request and Response text which is encrypted. Am I missing something in order to use a secure HTTP connection to do this?

我刚刚在我的 Windows 客户端上运行了它,唯一不同的是加密的请求和响应文本。为了使用安全的 HTTP 连接来执行此操作,我是否遗漏了什么?

NEW EDIT: This works with a non-HTTPS request such as: http://maps.googleapis.com/maps/api/geocode/json?address=UK&sensor=true. So I guess the problem is getting the iPhone to send the POST properly over SSL?

新编辑:这适用于非 HTTPS 请求,例如: http://maps.googleapis.com/maps/api/geocode/json?address=UK&sensor=true。所以我猜问题是让 iPhone 通过 SSL 正确发送 POST?

I am also using these methods:

我也在使用这些方法:

- (void) connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
        forAuthenticationChallenge:challenge];
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        return YES;
    }
}

This allows me to get this far. If I don't use them I get an error sent back saying:

这使我能够走到这一步。如果我不使用它们,我会收到一条错误消息:

The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mydomain.com” which could put your confidential information at risk.

此服务器的证书无效。您可能正在连接到一个伪装成“mydomain.com”的服务器,这可能会使您的机密信息处于危险之中。

回答by ingh.am

FIXED!

固定的!

Changed:

更改:

[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

to:

到:

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

You also need these two methods:

您还需要这两种方法:

- (void) connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
        forAuthenticationChallenge:challenge];
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        return YES;
    }
}

回答by Jon

I don't know Objective C at all, but try setting the Accept header to application/jsoninstead of application/jsonrequest.

我根本不知道 Objective C,但尝试将 Accept 标头设置为application/json而不是application/jsonrequest.

回答by Maulik Vekariya

change

改变

NSData *requestData = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];

to

NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];

回答by Vibhooti

dic is NSMutable Dictionary with object and keys. baseUrl is your server webservice url.

dic 是带有对象和键的 NSMutable 字典。baseUrl 是您的服务器网络服务 url。

 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic
                                                       options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
   NSString *encodedString = [jsonString base64EncodedString];

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@wsName",baseUrl]];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    [theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setValue:encodedString forHTTPHeaderField:@"Data"];