UI WebViewDelegate가 XMLHttpRequest를 감시하고 있지 않습니까?
UI WebViewDelegate는 XMLHttpRequest를 사용하여 이루어진 요구를 감시하지 않는다는 것이 사실입니까?그렇다면 이러한 요구를 감시할 수 있는 방법이 있습니까?
예를 들어 UI Web View Delegate는 이 정보를 수신하지 않습니다.-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSMutableURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
;
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.google.com", true);
xhr.onreadystatechange=function()
{
if (xhr.readyState==4)
{
alert(xhr.responseText);
}
}
xhr.send();
흥미로운 질문입니다.
이 작업을 수행하려면 JavaScript 핸들러와 UI WebView 위임 메서드의 두 가지 부분이 있습니다.JavaScript에서는 AJAX 요청이 생성되었을 때 이벤트를 트리거하도록 프로토타입 메서드를 수정할 수 있습니다.UI Web View 대리인을 통해 이러한 이벤트를 캡처할 수 있습니다.
JavaScript 핸들러
AJAX 요청이 있을 때 통지가 필요합니다.여기서 해결책을 찾았어요.
이 경우 코드를 작동시키기 위해 앱에 번들되어 있는 ajax_handler.js라는 리소스에 다음 JavaScript를 넣습니다.
var s_ajaxListener = new Object();
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
s_ajaxListener.callback = function () {
window.location='mpAjaxHandler://' + this.url;
};
XMLHttpRequest.prototype.open = function(a,b) {
if (!a) var a='';
if (!b) var b='';
s_ajaxListener.tempOpen.apply(this, arguments);
s_ajaxListener.method = a;
s_ajaxListener.url = b;
if (a.toLowerCase() == 'get') {
s_ajaxListener.data = b.split('?');
s_ajaxListener.data = s_ajaxListener.data[1];
}
}
XMLHttpRequest.prototype.send = function(a,b) {
if (!a) var a='';
if (!b) var b='';
s_ajaxListener.tempSend.apply(this, arguments);
if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
s_ajaxListener.callback();
}
이렇게 하면 실제로 브라우저의 위치를 요청에 대한 정보가 포함된 일부 구성 URL 스킴(이 경우 mpAjaxHandle)으로 변경할 수 있습니다.걱정하지 마세요, 저희 대표님이 이걸 잡아도 장소는 바뀌지 않을 거예요.
UI Web View 위임자
먼저 자바스크립트 파일을 읽어야 합니다.정적 변수에 저장하는 것이 좋습니다.+initialize를 사용하는 습관이 있습니다.
static NSString *JSHandler;
+ (void)initialize {
JSHandler = [[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ajax_handler" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil] retain];
}
다음으로 페이지 로딩이 완료되기 전에 이 JavaScript를 삽입하여 모든 이벤트를 수신하고 싶습니다.
- (void)webViewDidStartLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:JSHandler];
}
마지막으로 이벤트를 캡처하고 싶습니다.
URL 스킴은 구성되어 있기 때문에 실제로 그것을 따르고 싶지 않습니다.우리는 NO를 반환하고 모든 것이 정상입니다.
#define CocoaJSHandler @"mpAjaxHandler"
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[request URL] scheme] isEqual:CocoaJSHandler]) {
NSString *requestedURLString = [[[request URL] absoluteString] substringFromIndex:[CocoaJSHandler length] + 3];
NSLog(@"ajax request: %@", requestedURLString);
return NO;
}
return YES;
}
솔루션과 함께 샘플 프로젝트를 만들었는데 주최할 곳이 없습니다.당신이 그것을 주최할 수 있다면 메시지를 보내주시면 제가 이 게시물을 적절히 편집하겠습니다.
NSURLProtocol을 사용할 수 있습니다.예를 들어 XMLHttpRequest를 호출한 경우http://localhost/path
다음과 같이 처리할 수 있습니다.
@interface YourProtocol: NSURLProtocol
다음으로 구현의 경우:
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
return [request.URL.host isEqualToString:@"localhost"];
}
+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
- (void) startLoading
{
// Here you handle self.request
}
- (void)stopLoading
{
}
다음과 같이 프로토콜을 등록해야 합니다.
[NSURLProtocol registerClass:[YourProtocol class]];
NSURLProtocol의 하위 클래스를 구현 및 등록하면 UI WebView에서 모든 요청을 캡처할 수 있습니다.경우에 따라서는 오버킬이 될 수도 있지만 실제로 실행 중인 Javascript를 수정할 수 없다면 최선의 선택입니다.
이 경우 모든 요청을 캡처하고 모든 요청에 특정 HTTP 헤더를 삽입해야 합니다.NSURLProtocol을 구현하고 registerClass를 사용하여 등록한 후 요청이 관심 URL에 해당하는 경우 +(BOOL)canInitWithRequest:(NSURLRequest *) request에 대한 서브클래스의 YES에 응답함으로써 이 작업을 수행했습니다.그런 다음 NSURLConnection을 사용하여 프로토콜 클래스를 위임자로 설정하고 NSURLConnection의 위임 메서드를 NSURLProtocolClient로 리디렉션하여 수행할 수 있는 프로토콜의 다른 메서드를 구현해야 합니다.
사실인 것 같다. WebView를 사용하는 수 있는 기능 할 수 .사용 방법을 찾을 수 없는 한stringByEvaluatingJavaScriptFromString:
자바스크립트
다른 사람들이 언급했듯이 UI WebViewDelegate는 window.location과 iframe.src의 변경만을 감시합니다.
는, 의 URL 을 할 수 .<iframe>
★★★★★★★★★★★★★★★★★★.
예를 들어 다음과 같은 URL 스킴을 호출하는 경우
objc://my_action?arg1=1&arg2=2
js 파일:
/**
* @param msg : path of your query
* @param data : arguments list of your query
*/
var call_url = function(msg, data){
const scheme = "objc";
var url = scheme + '://' + msg;
if(data){
var pstr = [];
for(var k in data)
if(typeof data[k] != 'function')
pstr.push(encodeURIComponent(k)+"="+encodeURIComponent(data[k]));
url += '?'+pstr.join('&');
}
var i = document.createElement("iframe");
i.src = url;
i.style.opacity=0;
document.body.appendChild(i);
setTimeout(function(){i.parentNode.removeChild(i)},200);
}
//when you call this custom url scheme
call_url ("my_action", {arg1:1,arg2:2});
언급URL : https://stackoverflow.com/questions/5353278/uiwebviewdelegate-not-monitoring-xmlhttprequest
'it-source' 카테고리의 다른 글
SQL*PLUS for Oracle을 대체할 수 있는 좋은 방법이 있습니까? (0) | 2023.02.12 |
---|---|
wordpress rest api v2 분류법 용어를 나열하는 방법? (0) | 2023.02.12 |
범위 true를 사용하여 Angular Directive에서 상위 범위를 업데이트할 수 있습니까? (0) | 2023.02.12 |
범용 브라우저를 지원하는 Clip-Path를 대체하는 방법 (0) | 2023.02.12 |
AngularJs에서 외부 리소스를 로드하지 않습니다. (0) | 2023.02.12 |