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

发布于 2024-09-30 02:24:47 字数 3895 浏览 4 评论 0原文

我托管了一个 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];

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

- (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);
}

在这个响应中,我收到此消息:

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>

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

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

谢谢

编辑:

我刚刚习惯 CharlesProxy 来嗅探当我从 iPhone (模拟器)打电话时发生了什么这就是它给我的: alt text

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

我刚刚在我的 Windows 客户端上运行了这个,唯一不同的是请求和响应文本是加密的。为了使用安全 HTTP 连接来执行此操作,我是否缺少某些内容?

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

我也在使用这些方法:

- (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;
    }
}

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

该服务器的证书无效。您可能正在连接到冒充“mydomain.com”的服务器,这可能会使您的机密信息面临风险。

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:

    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 ASIHTTPPost instead but I can't get the demo to run in iOS4 :(

Thanks

EDIT:

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

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).

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?

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?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

云淡风轻 2024-10-07 02:24:47

固定的!

改为:

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

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

需要这两个方法:

- (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;
    }
}

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;
    }
}
不寐倦长更 2024-10-07 02:24:47

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

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

眼眸里的那抹悲凉 2024-10-07 02:24:47

更改

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

NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];

change

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

to

NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
葬シ愛 2024-10-07 02:24:47

dic 是带有对象和键的 NSMutable 字典。
baseUrl 是您的服务器 Web 服务 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"];

dic is NSMutable Dictionary with object and keys.
baseUrl is your server webservice 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"];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文