문제

이것의 목적 상, 나는 원래 URL이 http://host/form 그리고 새로운 URL입니다 https://host/form. (이 배송하기 전에 두 URL이 모두 안전해질 것입니다. 그러나 비 안전 보안은 이것을 테스트하기에 편리한 리디렉션처럼 보입니다.)

사용중인 웹 API에 액세스하고 있습니다 NSURLConnection 그것은 나를 다시 방향으로 만듭니다. 기본적으로 방금 제출 한 모든 것을 가져 가고 싶습니다. http://hostaform 그리고 그것을 다시 제출하십시오 https://host/form. 나는 이것이 기본 동작이라고 생각했지만, 리디렉션에서 몸이 사라지는 것처럼 보입니다.

그래서 나는 그것을 처리해야한다고 생각합니다 connection:willSendRequest:redirectResponse: 이벤트 NSURLConnection'의 대표와 신체를 다시 붙잡는다. 문제는이 메시지가 비밀리에 문서화 된 것처럼 보인다는 것입니다. 이 방법에서 내가 찾을 수있는 유일한 정보는 nsurlconnection 클래스 참조, 그다지 도움이되지 않습니다. 무엇보다도 여기에는 다음이 포함됩니다.

리디렉션 응답: 리디렉션을 일으킨 URL 응답. 이 방법이 리디렉션 처리에 대의원을 포함한 결과 로이 방법이 전송되지 않는 경우에는 NIL 일 수 있습니다.

이것이 무엇을 의미하는지 잘 모르겠습니다. 초기와 결합 willSendRequest: 호출, 나는 이것이 수단이라고 생각합니다 willSendRequest: 리디렉션 응답 전에 초기 요청에 대해서도 전송되고 있습니다. 그 맞습니까?

그래서 나는 대의원에 코드를 추가하여 시체를 여분의 시간을 유지하고 이것을 추가했습니다. willSendRequest: 매니저:

- (NSURLRequest *)connection: (NSURLConnection *)inConnection
             willSendRequest: (NSURLRequest *)inRequest
            redirectResponse: (NSURLResponse *)inRedirectResponse;
{
    if (inRedirectResponse) {
        NSMutableURLRequest *r = [[inRequest mutableCopy] autorelease];
        [r setURL: [inRedirectResponse URL]];
        [r setHTTPBody: body];
        return r;
    } else {
        return inRequest;
    }
}

작동하지 않습니다. 그러나 이것이 올바른 접근법인지 확실하지 않습니다. 나에게 지나치게 해킹 된 것 같습니다. 나는 무엇을해야합니까? 이것은 어디서나 문서화되어 있습니까? Apple의 문서 나 지금까지 Google을 사용하는 데 유용한 것은 발견되지 않았습니다.

(이것은 iPhone에 있지만,이 수업에는 큰 차이가없는 것 같습니다.)

도움이 되었습니까?

해결책

메모가 있습니다 RFC 2616 섹션 10.3.2 이 행동에 대해 :

참고 : 301 상태 코드를 수신 한 후 포스트 요청을 자동으로 리디렉션하면 일부 기존 HTTP/1.0 사용자 에이전트가 GET 요청으로 잘못 변경됩니다.

따라서이 행동은 비표준이지만 역사적 인 것 같습니다. 저것 GET 요청은 아닙니다 POST, 그리고 페이로드가 누락됩니다.

흥미롭게도 이것은 같은 섹션에 있습니다.

GET 또는 HEAD 이외의 요청에 따라 301 상태 코드가 수신되면 사용자 에이전트는 요청이 발행 된 조건을 변경할 수 있으므로 사용자가 확인할 수없는 한 요청을 자동으로 리디렉션해서는 안됩니다.

그것은 매우 분명하고 우리가 이것을 고칠 수 없다는 것을 나타내는 것처럼 보이지만, 우리가 선택한 서비스 (또는 제어)를 위해 자신의 웹 서비스 클라이언트의 목적으로 이것을 무시하는 것이 아마도 가장 나쁜 대안이라고 생각합니다.

그래서 우리는 이것을 어떻게 해결합니까?

대신 willSendResponse: 원래 질문에서 나는 이것을 사용하고 있습니다.

- (NSURLRequest *)connection: (NSURLConnection *)connection
             willSendRequest: (NSURLRequest *)request
            redirectResponse: (NSURLResponse *)redirectResponse;
{
    if (redirectResponse) {
        // we don't use the new request built for us, except for the URL
        NSURL *newURL = [request URL];
        // Previously, store the original request in _originalRequest.
        // We rely on that here!
        NSMutableURLRequest *newRequest = [_originalRequest mutableCopy];
        [newRequest setURL: newURL];
        return newRequest;
    } else {
        return request;
    }
}

여기서 아이디어는 새로운 요청을 복제하고 코코아 터치가 저를 보내는 것과 동일하게 만들려고 시도하는 대신 원래 요청의 클론을 만들고 코코아 터치가 보낸 요청과 일치하도록 URL 만 변경합니다. 원래의 요청은 여전히입니다 POST 페이로드가 첨부 된 상태에서.

서버를 제어하면 읽을 가치가 있습니다. RFC 2616, 섹션 10.3 더 나은 코드가 있는지 확인하기 위해 전체적으로 사용할 수 있습니다 (물론 iOS가 더 나은 코드를 처리하는지 확인하는 동안).

또한 리디렉션 된 요청의 변이 가능한 사본을 만들고 HTTP 메소드를 원래 요청의 HTTP 방법으로 바꿀 수도 있습니다. 동일한 일반 원칙이지만, 그것은 기존이 아닌 새로운 요청에서 사물을 유지하는 것을 선호합니다. 어떤 상황에서는 더 잘 작동 할 수 있지만 아직 테스트하지 않았습니다.

다른 팁

서버에서 보낸 HTTP 응답 상태 코드를 확인하여 게시물을 보내거나 반복할지 여부를 결정해야합니다. 303 (또는 302)의 경우 GET 요청을 보내십시오. 307의 경우 게시물을 반복하십시오.

리디렉션과 같은 문제가있었습니다. Ajsoaks에게 감사합니다! 나는 그가 제안한대로 시도했고 문제가 해결된다.

그래서 게시물 메소드를 통해 사용자 이름과 비밀번호를 게시하려고했는데 서버가 내 요청을 리디렉션하는 것을 보았습니다. Ajsoaks가 말했듯이, 302 오류가 있으면 요청을 반복해야하지만 이번에는 이전 게시물 대신 GET 메소드를 사용합니다.

... 어느 시점에서 당신은 다음 줄이 있습니다 : ... 당신의 ibaction (버튼 눌린) 방법이나 원하는 곳이면 내부에있을 수 있습니다 ...

NSMutableString *postString = [[NSMutableString alloc] init];

[postString appendString:@"username=YourUsername&password=YourPassword"];

    //the original URL (https means that it supports SSL protocol)
    //it doesn't change anything, don't worry about it
NSURL *URL = [NSURL URLWithString:@"https://loginWebpageURL"];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];

[request setHTTPMethod:@"POST"];    
[request setValue:[NSString stringWithFormat:@"%d", [postString length]] forHTTPHeaderField:@"Content-length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

[NSURLConnection connectionWithRequest:request delegate:self];

[postString release];
[request release];

다음과 같은 시그니처와 함께 리디렉션 NSURLConnection Delegate 메소드를 구현해야합니다.

- (NSURLRequest *)connection:(NSURLConnection *)connection
            willSendRequest:(NSURLRequest *)request
           redirectResponse:(NSURLResponse *)redirectResponse

이 메소드 내에서 서버의 오류 302 또는 303이있는 경우 코드 벨로우와 유사한 것을 구현해야합니다. 보는 코드를 복사하여 새 URL (리디렉션)으로 바꾸십시오. 브라우저에서 볼 수있는 새로운 URL이거나 원하는 경우 FireBug (Firefox 플러그인) 또는 Safari Web Inspector로 확인하는 것이 매우 유용합니다. FireBug를 사용하는 경우 "NET"옵션에서 찾을 수 있습니다.

if (redirectResponse) {

    NSLog(@"REDIRECT");
    NSMutableURLRequest *requestTmp = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://areaclienti.tre.it/selfcare/areaclienti133/4552_infoCosti_ITA_HTML.xsl"]];

    return [requestTmp autorelease];
}

//return original request in case thay there is no redirecting...
else return request;

NSURLConnection은 "WillSendRequest : (nsurlRequest *) Inverquest"의 리디렉션 요청에 OriginalRequest 헤더를 추가하지 않습니다.

리디렉션 된 요청에 "originalRequest.headers"를 추가 하여이 문제를 해결할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top