GVKun编程网logo

objective-c – 通过Cocoa中的NSURLRequest/NSURLConnection接收HTTP头

11

对于想了解objective-c–通过Cocoa中的NSURLRequest/NSURLConnection接收HTTP头的读者,本文将是一篇不可错过的文章,并且为您提供关于cocoa–在委托中区分N

对于想了解objective-c – 通过Cocoa中的NSURLRequest/NSURLConnection接收HTTP头的读者,本文将是一篇不可错过的文章,并且为您提供关于cocoa – 在委托中区分NSURLConnection对象、HttpURLConnection和HttpsURLConnection、iOS 9上的NSURLConnection不使用HTTP / 2协议、iOS 9中的HTTPS请求:NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)的有价值信息。

本文目录一览:

objective-c – 通过Cocoa中的NSURLRequest/NSURLConnection接收HTTP头

objective-c – 通过Cocoa中的NSURLRequest/NSURLConnection接收HTTP头

我一直在研究如何通过NSURLConnection发出的请求来接收HTTP头。通常情况下,请求的内容与以下内容一样简单:

NSURLConnection *connection = [[NSURLConnection alloc]
    initWithRequest:request
        delegate:self];

我在Apple丰富的文档中发现接收响应标头的唯一方法是通过使用以下NSURLConnection类方法的同步调用:

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

这里我可以很容易的引用NSURLResponse类型的响应对象。这里的问题是我还没准备好通过移动设备进行同步请求,尤其是具有高延迟的网络(如EDGE)。是否可以使用NSURLConnection的默认异步行为获得类似的结果?

解决方法

在你的连接代理中,添加-connection:didReceiveResponse:方法。如果您正在执行标准HTTP请求,则传入的NSURLResponse对象实际上将是一个NSHTTPURLResponse对象,并响应-allHeaderFields消息。这应该是你要找的。

cocoa – 在委托中区分NSURLConnection对象

cocoa – 在委托中区分NSURLConnection对象

我有两个请求一个接一个地开始.像这样开始请求

NSURL *url = [NSURL URLWithString:[Nsstring stringWithFormat:@"http://www.google.com"]];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
NSURLConnection * connection = [[NSURLConnection alloc]
                                initWithRequest:request
                                delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop]
                      forMode:NSDefaultRunLoopMode];
[connection start];

和另一个这样开始的请求.

NSURL *url1 = [NSURL URLWithString:[Nsstring stringWithFormat:@"http://www.apple.com"]];
NSURLRequest *request1 = [NSURLRequest requestWithURL:url1 cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
NSURLConnection *connection1 = [[NSURLConnection alloc] initWithRequest:request1 delegate:self];
[connection1 release];

如何在委托方法中区分这两者?

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{}

不希望为此目的保留任何额外的类变量.

解决方法

这很简单 :

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
     if (connection == connection1)
     {
         //It's for connection1.
     }
     else if (connection == connection2)
     {
         //It's for connection2.
     }
}

你可以通过这个美丽的SO问题:Managing multiple asynchronous NSURLConnection connections

HttpURLConnection和HttpsURLConnection

HttpURLConnection和HttpsURLConnection

/** 
     * 发起https请求并获取结果 
     *  
     * @param requestUrl 请求地址 
     * @param requestMethod 请求方式(GET、POST) 
     * @param outputStr 提交的数据 
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 
     */  
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr){
        JSONObject jsonObject = null;  
        StringBuffer buffer = new StringBuffer();  
        try {  
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化  
            TrustManager[] tm = { new MyX509TrustManager() };  
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
            sslContext.init(null, tm, new java.security.SecureRandom());  
            // 从上述SSLContext对象中得到SSLSocketFactory对象  
            SSLSocketFactory ssf = sslContext.getSocketFactory();  
  
            URL url = new URL(requestUrl);  
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
            httpUrlConn.setSSLSocketFactory(ssf);  
  
            httpUrlConn.setDoOutput(true);  
            httpUrlConn.setDoInput(true);  
            httpUrlConn.setUseCaches(false);  
            // 设置请求方式(GET/POST)  
            httpUrlConn.setRequestMethod(requestMethod);  
  
           // if ("GET".equalsIgnoreCase(requestMethod))  
                httpUrlConn.connect();  
  
            // 当有数据需要提交时  
            if (null != outputStr) {  
                OutputStream outputStream = httpUrlConn.getOutputStream();  
                // 注意编码格式,防止中文乱码  
                outputStream.write(outputStr.getBytes("UTF-8"));  
                outputStream.close();  
            }  
  
            // 将返回的输入流转换成字符串  
            InputStream inputStream = httpUrlConn.getInputStream();  
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
  
            String str = null;  
            while ((str = bufferedReader.readLine()) != null) {  
                buffer.append(str);  
            }  
            bufferedReader.close();  
            inputStreamReader.close();  
            // 释放资源  
            inputStream.close();  
            inputStream = null;  
            httpUrlConn.disconnect();  
            jsonObject = JSONObject.fromObject(buffer.toString());  
        } catch (ConnectException ce) {  
            log.error("Weixin server connection timed out.");  
        } catch (Exception e) {  
            log.error("https request error:{}", e);  
        }  
        return jsonObject;  
    }  

/** 
     * 发起http请求并获取结果 
     *  
     * @param requestUrl 请求地址 
     * @param requestMethod 请求方式(GET、POST) 
     * @param outputStr 提交的数据 
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 
     */  
public static String httpRequest(String requestUrl, String requestMethod, String outputStr){
        JSONObject jsonObject = null;  
        StringBuffer buffer = new StringBuffer();  
        try {  
            URL url = new URL(requestUrl);  
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  
  
            httpUrlConn.setDoOutput(true);  
            httpUrlConn.setDoInput(true);  
            httpUrlConn.setUseCaches(false);  
            // 设置请求方式(GET/POST)  
            httpUrlConn.setRequestMethod(requestMethod);  
  
            httpUrlConn.connect();  
  
            // 当有数据需要提交时  
            if (null != outputStr) {  
                OutputStream outputStream = httpUrlConn.getOutputStream();  
                // 注意编码格式,防止中文乱码  
                outputStream.write(outputStr.getBytes("UTF-8"));  
                outputStream.close();  
            }  
  
            // 将返回的输入流转换成字符串  
            InputStream inputStream = httpUrlConn.getInputStream();  
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
  
            String str = null;  
            while ((str = bufferedReader.readLine()) != null) {  
                buffer.append(str);  
            }  
            bufferedReader.close();  
            inputStreamReader.close();  
            // 释放资源  
            inputStream.close();  
            inputStream = null;  
            httpUrlConn.disconnect();  
            
/*            if(!"".equals(buffer.toString().trim())){
            jsonObject = JSONObject.fromObject(buffer.toString());  
            }*/
        } catch (ConnectException ce) {  
            log.error("Weixin server connection timed out.");  
        } catch (Exception e) {  
            log.error("https request error:{}", e);  
        }  
        return buffer.toString();  
    } 

 

iOS 9上的NSURLConnection不使用HTTP / 2协议

iOS 9上的NSURLConnection不使用HTTP / 2协议

我在Jetty 9.3服务器上配置了HTTP / 2,它有一个有效的证书和Ssllabs.com给它一个A级安全配置.

使用Chrome浏览器到https://example.com浏览加载了正确的响应,它还报告使用了“h2”(HTTP / 2“)协议.

但是当尝试使用NSURLConnection从iOS 9访问相同的URL时,我可以在请求日志中看到它使用了HTTP 1.1.如果我在我的服务器上禁用HTTP 1.1,请求将在iOS 9上失败(但仍然在Chrome上成功).

NSURLConnection代码 –

let url = NSURL(string: "https://example.com")
request = NSURLRequest(URL: url,cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData,timeoutInterval: 10)

connection = NSURLConnection(request: request,delegate: self,startImmediately: true)

服务器的ALPN调试输出 –

[S] ALPN protocols [spdy/3.1,spdy/3,http/1.1] received from client for 1e5e2487[SSLEngine[hostname=3.4.5.6 port=52090] SSL_NULL_WITH_NULL_NULL]
[S] ALPN protocol 'http/1.1' selected for 1e5e2487[SSLEngine[hostname=3.4.5.6 port=52090] SSL_NULL_WITH_NULL_NULL]

在WWDC 2015中,据称iOS 9中的NSURLRequest支持HTTP / 2,但客户端应用声称支持spdy / 3.1,spdy / 3,http / 1.1,没有http / 2.没有设置NSAppTransportSecurity异常.

我尝试在运行应用程序的同一个iPhone模拟器上使用Safari连接到服务器,这次它工作并使用HTTP / 2,这里是ALPN调试输出 –

[S] ALPN protocols [h2,h2-16,h2-15,h2-14,spdy/3.1,http/1.1] received from client for 7b50217d[SSLEngine[hostname=3.4.5.6 port=52247] SSL_NULL_WITH_NULL_NULL]
[S] ALPN protocol 'h2' selected for 7b50217d[SSLEngine[hostname=3.4.5.6 port=52247] SSL_NULL_WITH_NULL_NULL]

任何想法为什么它不在应用程序内使用HTTP / 2?

解决方法

HTTP/2仅受 NSURLSession支持.在iOS 9中已弃用 NSURLConnection.以下是标题中的引用:

iOS 9中的HTTPS请求:NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)

iOS 9中的HTTPS请求:NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)

我正在更新我的应用程序以适应苹果的新 ATS.没有对Plist-Info的任何更改,以下代码在vanilla iOS 9模拟器中的sendSynchronousRequest()中引发错误.
NSURL *url  =[NSURL URLWithString:@"https://Google.com"];
NSMutableuRLRequest *request = [[NSMutableuRLRequest alloc]init];
[request setHTTPMethod:@"GET"];
[request setURL:url];

NSURLResponse *urlResponse = nil;
NSError *error = nil;    
NSData *reponse = [NSURLConnection sendSynchronousRequest:request
                                        returningResponse:&urlResponse
                                                    error:&error];

错误:

NSURLSession / NSURLConnection HTTP加载失败(kcfStreamErrorDomainSSL,-9802)

对这个问题可能背后有什么想法?

Ps:据了解,NSURLConnection已被弃用.但是,如果我在Plist中添加了AllowArbitraryLoads,那么这个调用可以找到.

解决方法

NSURLSession / NSURLConnection HTTP加载失败(kcfStreamErrorDomainSSL,-9802)
对应于服务器不支持“Forward Secrecy”.

要解决此问题,请将域异常添加到.plist文件中,如下所示:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>test.testdomain.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NstemporaryExceptionRequiresForwardSecrecy</key>
      <false/>
    </dict>

今天关于objective-c – 通过Cocoa中的NSURLRequest/NSURLConnection接收HTTP头的分享就到这里,希望大家有所收获,若想了解更多关于cocoa – 在委托中区分NSURLConnection对象、HttpURLConnection和HttpsURLConnection、iOS 9上的NSURLConnection不使用HTTP / 2协议、iOS 9中的HTTPS请求:NSURLSession / NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)等相关知识,可以在本站进行查询。

本文标签: