WKWebView的使用和各種坑的解決方法(OC+Swift)


https://www.jianshu.com/p/403853b63537

 

雖然WKWebView是在Apple的WWDC 2014隨iOS 8和OS X 10.10出來的,是為了解決UIWebView加載速度慢、占用內存大的問題。但是由於之前還要適配iOS7,又不想做兩套加載頁面(主要是因為懶),所以就沒有使用。現在項目都適配iOS 8以上了,所以就開始使用WKWebView了,但是發現在使用的時候有好多坑,希望這篇文章能帶大家繞過坑,更好的使用WKWebView。

 

 

這篇文章主要介紹了以下問題,方便小伙伴們查閱:

 

 

 

 

WKWebView的基本介紹和使用

 

 

 

 

 

WKWebView和JavaScript的交互

 

 

 

 

解決WKWebView加載POST請求無法發送參數問題

 

 

 

 

WKWebView的基本介紹和使用

 

WKWebView的幾個代理方法

 

WKWebView是蘋果在iOS 8中引入的新組件,目的是給出一個新的高性能的WebView解決方案,擺脫過去 UIWebView的老、舊、笨重,特別是內存占用量巨大的問題,它使用Nitro JavaScript引擎,這意味着所有第三方瀏覽器運行JavaScript將會跟safari一樣快。

 

看到我這篇文章的小伙伴,對iOS的開發應該有一定的了解,肯定用過UIWebView,現在就用UIWebView和WKWebView的代理方法做一個對比。

 

 

加載狀態的回調(用來跟蹤頁面加載的過程(頁面開始加載、加載完成、加載失敗的方法),還可以決定是否跳轉):

 

准備加載頁面

 

 

 

        UIWebViewDelegate: - webView:shouldStartLoadWithRequest:navigationType

        WKNavigationDelegate: - webView:didStartProvisionalNavigation:

 

2. **內容開始加載**`(view的過渡動畫可在此方法中加載)`

 

        UIWebViewDelegate: - webViewDidStartLoad:

        WKNavigationDelegate: - webView:didCommitNavigation:

 

3. **頁面加載完成**`(view的過渡動畫的移除可在此方法中進行)`

 

        UIWebViewDelegate: - webViewDidFinishLoad:

        WKNavigationDelegate: - webView:didFinishNavigation:

 

4. **頁面加載失敗**

 

        UIWebViewDelegate: - webView:didFailLoadWithError:

        WKNavigationDelegate: - webView:didFailNavigation:withError:

        WKNavigationDelegate: - webView:didFailProvisionalNavigation:withError:

 

此外,WKWebKit還有三個頁面跳轉的代理方法:

 

頁面跳轉的代理

 

接收到服務器跳轉請求的代理

 

 

 

        WKNavigationDelegate: - webView:didReceiveServerRedirectForProvisionalNavigation:

 

2. **在收到響應后,決定是否跳轉的代理**

 

        WKNavigationDelegate: - webView:decidePolicyForNavigationResponse:decisionHandler:

 

3. **在發送請求之前,決定是否跳轉的代理**

 

        WKNavigationDelegate: - webView:decidePolicyForNavigationAction:decisionHandler:

 

 

WKWebView增加的屬性

 

WKWebViewConfiguration *configuration:初始化WKWebView的時候的配置,后面會用到

WKBackForwardList *backForwardList:相當於訪問歷史的一個列表

double estimatedProgress:進度,有這個之后就不用自己寫假的進度條了

 

WKWebView的使用

OC代碼:

    // 創建WKWebView

    WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];

    // 設置訪問的URL

    NSURL *url = [NSURL URLWithString:@"http://www.jianshu.com"];

    // 根據URL創建請求

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // WKWebView加載請求

    [webView loadRequest:request];

    // 將WKWebView添加到視圖

    [self.view addSubview:webView];

 

Swift代碼:

    // 創建WKWebView

    let webView = WKWebView(frame: UIScreen.mainScreen().bounds)

    // 設置訪問的URL

    let url = NSURL(string: "http://www.jianshu.com")

    // 根據URL創建請求

    let requst = NSURLRequest(URL: url!)

    // WKWebView加載請求

    webView.loadRequest(requst) 

    // 將WKWebView添加到視圖

    view.addSubview(webView)

 

可以看到很簡單,和UIWebView並沒有多少差別,然而性能就刷刷刷的提上去了,是不是很爽呢?如果你只是簡單的集成個Web頁到App,這些已經夠了。不過很多時候並沒有那么簡單,還需要處理各種東西,那么接着往后看。

 

 

WKWebView和JavaScript的交互

 

在WebKit框架中,有WKWebView可以替換UIKit的UIWebView和AppKit的WebView,而且提供了在兩個平台可以一致使用的接口。WebKit框架使得開發者可以在原生App中使用Nitro來提高網頁的性能和表現,Nitro就是Safari的JavaScript引擎,WKWebView不支持JavaScriptCore的方式但提供message handler的方式為JavaScript與Native通信。(這個引自天狐博客,更多的與UIWebView或者WKWebView的交互方法可以在這里看到。下面部分代碼(例如JS)也是竊取這個作者的,尊重原著,所以把原博客地址放這里,與JS交互寫的比我好多了。)

 

Native調用JavaScript方法

原生調用JavaScript的代碼需要在頁面加載完成之后,就是在 - webView:didFinishNavigation:代理方法里面

OC代碼:

[webView evaluateJavaScript:@"showAlert('奏是一個彈框')" completionHandler:^(id item, NSError * _Nullable error) {

        // Block中處理是否通過了或者執行JS錯誤的代碼

    }];

 

Swift代碼:

webView.evaluateJavaScript("showAlert('奏是一個彈框')") { (item, error) in

            // 閉包中處理是否通過了或者執行JS錯誤的代碼

        }   

 

大家可以看到這段JS代碼是最簡單的彈出一個Alert的代碼,后面WKWebView加載POST請求參數問題中還會有一個加載POST請求的JS代碼,先不要管它了,請各位看官繼續往后翻,看看JavaScript怎么調用Native的方法。

 

JavaScript調用Native方法

 

 

JavaScript的配置

JavaScript調用Native的方法就需要前端和Native的小伙伴們配合了,需要前端的小伙伴在JS的方法中調用:

window.webkit.messageHandlers.NativeMethod.postMessage("就是一個消息啊");

 

這行代碼。請注意,這個NativeMethod是和App中要統一的,配置方法將在下面的Native中書寫。

 

 

Native App的代碼配置

下面該Native的代碼的配置了,細心的小伙伴可能已經發現了,創建WKWebView的時候,除了有- initWithFrame:方法外,還有一個高端的方法:- initWithFrame:configuration:方法。那句名言是誰說的來着:普通玩家選擇推薦配置,高端玩家選擇自定義配置,就當是我說的吧(那個拿鞋的把鞋穿上吧,我承認不是我說的😂)。這個方法就是用來自定義配置的,具體怎么自定義呢,童鞋們接着往下看吧。

OC代碼:

    // 創建配置

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];

    // 創建UserContentController(提供JavaScript向webView發送消息的方法)

    WKUserContentController* userContent = [[WKUserContentController alloc] init];

    // 添加消息處理,注意:self指代的對象需要遵守WKScriptMessageHandler協議,結束時需要移除

    [userContent addScriptMessageHandler:self name:@"NativeMethod"];

    // 將UserConttentController設置到配置文件

    config.userContentController = userContent;

    // 高端的自定義配置創建WKWebView

    WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:config];

    // 設置訪問的URL

    NSURL *url = [NSURL URLWithString:@"http://www.jianshu.com"];

    // 根據URL創建請求

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // WKWebView加載請求

    [webView loadRequest:request];

    // 將WKWebView添加到視圖

    [self.view addSubview:webView];

 

Swift代碼:

    // 創建配置

    let config = WKWebViewConfiguration()

    // 創建UserContentController(提供JavaScript向webView發送消息的方法)

    let userContent = WKUserContentController()

    // 添加消息處理,注意:self指代的對象需要遵守WKScriptMessageHandler協議,結束時需要移除

    userContent.addScriptMessageHandler(self, name: "NativeMethod")

    // 將UserConttentController設置到配置文件

    config.userContentController = userContent

    // 高端的自定義配置創建WKWebView

    let webView = WKWebView(frame: UIScreen.mainScreen().bounds, configuration: config)

    

    // 設置訪問的URL

    let url = NSURL(string: "http://www.jianshu.com")

    // 根據URL創建請求

    let requst = NSURLRequest(URL: url!)

    // 設置代理

    webView.navigationDelegate = self

    // WKWebView加載請求

    webView.loadRequest(requst)

    

    // 將WebView添加到當前view

    view.addSubview(webView)

 

可以看到,添加消息處理的handler的name,就是JavaScript中調用時候的NativeMethod,這兩個要保持一致。請把URL換成你自己的。

請注意第6行的代碼配置當前ViewController為MessageHandler,需要服從WKScriptMessageHandler協議,如果出現警告⚠️,請檢查是否服從了這個協議。

注意!注意!注意:上面將當前ViewController設置為MessageHandler之后需要在當前ViewController銷毀前將其移除,否則會造成內存泄漏。

移除的代碼如下:

OC代碼:

[webView.configuration.userContentController removeScriptMessageHandlerForName:@"NativeMethod"];

 

Swift代碼:

webView.configuration.userContentController.removeScriptMessageHandlerForName("NativeMethod")

 

請注意這個Name和上面創建WKWebView的配置中注冊的名字是一樣的,要保持對應。

好了,現在萬事俱備,只欠東風了。東風是什么呢,就是該在哪兒處理。可以看到WKScriptMessageHandler的協議里面只有一個方法,就是:

- userContentController:didReceiveScriptMessage:

 

相信聰明的你已經猜到了。是的,就是在這個代理方法里面操作:如果JavaScript執行已經寫好的:window.webkit.messageHandlers.NativeMethod.postMessage("就是一個消息啊");這行代碼,這個代理方法就會走,並且會有個WKScriptMessage的對象,這個WKScriptMessage對象有個name屬性,拿到之后你會發現,就是我們注冊的NativeMethod這個字符串,這時候你就可以手動調用Native的方法了。如果有多個方法需要調用的話怎么辦,看到JavaScript中postMessage()方法有一個參數了沒有,可以根據這里的參數來區分調用原生App的哪個方法。

代碼很簡單,就不寫了。什么?你說你還需要寫?好吧,那我還是貼出來吧:

OC代碼:

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {

        // 判斷是否是調用原生的

        if ([@"NativeMethod" isEqualToString:message.name]) {

            // 判斷message的內容,然后做相應的操作

            if ([@"close" isEqualToString:message.body]) {

        

            }

        }

    }

 

Swift代碼:

    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {

        // 判斷是否是調用原生的

        if "NativeMethod" == message.name {

            // 判斷message的內容,然后做相應的操作

            if "close" == message.body as! String {

            

            }

        }

    }

 

上面的方法就可以獲取到JavaScript發送的Message了,JavaScript可以這樣調用:window.webkit.messageHandlers.NativeMethod.postMessage("close");,這時候上面的代理方法的兩個if判斷都能通過,不同的操作可增加里面的if語句的分支判斷message的內容來進行不同的Native代碼的調用,也就是JavaScript的postMessage方法的參數的不同來區分不同的操作。

好了,現在WKWebView和JavaScript的簡單交互你也會了。用WKWebView的時候貌似也還算開心。但是不要高興的太早,下面就要有坑了。

 

 

 

解決WKWebView加載POST請求無法發送參數問題

 

也許你用UIWebView加載過POST請求的頁面,感覺並沒有什么難點或者需要注意的地方,那真的是圖樣圖森破了,因為我也這樣天真過。直到我踩了很多坑之后,我才發現夢想與現實之間的差別,不過沒關系,我又要說另一句名言了:沒有挖不到的牆角...,咳咳咳,說錯了,請重新來BGM,跟我一起說:沒有解決不了的Bug,只有不努力的碼農!(各位架構師、高級開發工程師請手下留情,我說的碼農是我😂)

 

來來來,先來一發POST請求加載WebView。你會說,這還不easy?下面就來一個,走起:

OC代碼:

    // 創建WKWebView

    WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];

    // 設置訪問的URL

    NSURL *url = [NSURL URLWithString:@"http://www.example.com"];

    // 根據URL創建請求

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    // 設置請求方法為POST

    [request setHTTPMethod:@"POST"];

    // WKWebView加載請求

    [webView loadRequest:request];

    // 將WKWebView添加到視圖

    [self.view addSubview:webView];

 

Swift代碼:

    // 創建WKWebView

    let webView = WKWebView(frame: UIScreen.mainScreen().bounds)

    // 設置訪問的URL

    let url = NSURL(string: "http://www.example.com")

    // 根據URL創建請求

    let requst = NSMutableURLRequest(URL: url!)

    // 設置請求方法為POST

    requst.HTTPMethod = "POST"

    // WKWebView加載請求

    webView.loadRequest(requst)

    // 將WKWebView添加到視圖

    view.addSubview(webView)

 

這樣確實加載POST請求的網頁成功了(注意請把鏈接換成自己的),你一定露出了得意的笑容。但是騷年,不要高興的太早,這只是一個簡單的POST請求,還沒有添加參數呢。於是乎,你又說:那更簡單,在第9行插入如下代碼即可(比方說這個接口是登錄):

OC代碼:

    // 設置請求參數

    [request setHTTPBody:[@"username=aaa&password=123" dataUsingEncoding:NSUTF8StringEncoding]];

 

Swift代碼:

    // 設置請求參數

    requst.HTTPBody = "username=aaa&password=123".dataUsingEncoding(NSUTF8StringEncoding)

 

這種方法在UIWebView里面是沒有問題的,所以你認為在這里也應該是沒有問題的。從理論上講應該是這樣的,但是我要恭喜你了,這是WKWebView的Bug,讓你給碰到了。這里寫的POST請求沒有問題,但是就是不會把這兩個參數傳上去的,不信你可以試試(截止我發表這篇博客的日期,iOS 9.3並沒有修復此問題)。

好了,不廢話了(其實已經說了很多廢話了),下面看解決辦法(如果你需要適配iOS 8請直接使用方法2):

 

使用NSURLSession發送一個請求,然后把請求下來的數據當作本地HTML加載

使用JavaScript解決WKWebView無法發送POST參數問題

 

1. 使用NSURLSession解決WKWebView無法POST參數的問題(性能和結果都可能有問題,不推薦使用)

當發現POST無法傳遞參數的時候,我首先想到的是換個方法來,就是用一般的請求方式:NSURLSession發送請求,然后把接收到的數據轉化成字符串,然后再用WKWebView加載。大家可能已經看出來了,需要把整個網頁放到內存中或着放到本地然后再加載,所以肯定消耗內存呀。下面貼代碼吧:

OC代碼:

    // 創建WKWebView

    WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];

    // 將WKWebView添加到當前View

    [self.view addSubview:webView];

    // 設置訪問的URL

    NSURL *url = [NSURL URLWithString:@"http://www.example.com"];

    // 根據URL創建請求

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    // 設置請求方法為POST

    [request setHTTPMethod:@"POST"];

    // 設置請求參數

    [request setHTTPBody:[@"username=aaa&password=123" dataUsingEncoding:NSUTF8StringEncoding]];

    

    // 實例化網絡會話

    NSURLSession *session = [NSURLSession sharedSession];

    // 創建請求Task

    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        

        // 將請求到的網頁數據用loadHTMLString 的方法加載

        NSString *htmlStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        [webView loadHTMLString:htmlStr baseURL:nil];

    }];

    // 開啟網絡任務

    [task resume];

 

Swift代碼:

    // 創建WKWebView

    let webView = WKWebView(frame: UIScreen.mainScreen().bounds)

    // 設置訪問的URL

    let url = NSURL(string: "http://www.example.com")

    // 根據URL創建請求

    let requst = NSMutableURLRequest(URL: url!)

    // 設置請求方法為POST

    requst.HTTPMethod = "POST"

    // 設置請求參數

    requst.HTTPBody = "username=aaa&password=123".dataUsingEncoding(NSUTF8StringEncoding)

    // 將WKWebView添加到視圖

    view.addSubview(webView)

    

    // 實例化網絡會話

    let session = NSURLSession.sharedSession()

  

    // 創建請求Task

    let task = session.dataTaskWithRequest(requst) { (data, response, error) in

        webView.loadHTMLString(String(data: data!, encoding: NSUTF8StringEncoding)!, baseURL: nil)

    }

    task.resume()

 

當你用iOS 9以上的設備的時候,貌似完全沒有一點問題,只是需要請求下來再放而已。但是注意前提條件:iOS 9,當你用iOS 8的時候,發現你的網頁的樣式和JavaScript事件全部沒有了。是不是有一種呵呵的沖動,那你就盡情呵呵吧。如果你要適配iOS 8,那么這個方法也不符合你的氣質。

其實這個東西和加載本地網頁無法加載CSS樣式和JS一樣,如果你也加載本地HTML文件出現問題,請查看Jay神的WKWebView使用遇到的坑。盡給別人打廣告了,呵呵,聲明一下啊:我跟這些人木有關系,只是為了方便大家查閱而已,誰讓我那么的大公無私呢😂。

好了,好了,來看一個更好的解決辦法吧:

2. 使用JavaScript解決WKWebView無法發送POST參數問題

 

開始之前我先說一下實現思路,方便大家理解,如果出錯了也能知道錯誤的地方:

 

 

 

將一個包含JavaScript的POST請求的HTML代碼放到工程目錄中

加載這個包含JavaScript的POST請求的代碼到WKWebView

 

加載完成之后,用Native調用JavaScript的POST方法並傳入參數來完成請求

 

 

 

 

創建包含JavaScript的POST請求的HTML代碼

相關代碼:

<html>

<head>

    <script>

        //調用格式: post('URL', {"key": "value"});

        function post(path, params) {

            var method = "post";

            var form = document.createElement("form");

            form.setAttribute("method", method);

            form.setAttribute("action", path);

 

            for(var key in params) {

                if(params.hasOwnProperty(key)) {

                    var hiddenField = document.createElement("input");

                    hiddenField.setAttribute("type", "hidden");

                    hiddenField.setAttribute("name", key);

                    hiddenField.setAttribute("value", params[key]);

 

                    form.appendChild(hiddenField);

                }

            }

            document.body.appendChild(form);

            form.submit();

        }

    </script>

</head>

<body>

</body>

 

 

 

</html>

```

將這段代碼拷貝下來,然后粘貼到文本編輯器中,名字可以隨意起,比方說保存為:JSPOST.html,然后拷貝到工程目錄中,記得選擇對應的Target和勾選Copy items if needed(默認應該是勾選的)。這時候,就可以用這段JavaScript代碼來發送帶參數的POST請求了。

 

 

將對應的JavaScript代碼通過加載本地網頁的形式加載到WKWebView

OC代碼:

// JS發送POST的Flag,為真的時候會調用JS的POST方法(僅當第一次的時候加載本地JS)

self.needLoadJSPOST = YES;

// 創建WKWebView

self.webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];

//設置代理

self.webView.navigationDelegate = self;

// 獲取JS所在的路徑

NSString *path = [[NSBundle mainBundle] pathForResource:@"JSPOST" ofType:@"html"];

// 獲得html內容

NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

// 加載js

[self.webView loadHTMLString:html baseURL:[[NSBundle mainBundle] bundleURL]];

// 將WKWebView添加到當前View

[self.view addSubview:self.webView];

 

Swift代碼:

// JS發送POST的Flag,為真的時候會調用JS的POST方法(僅當第一次的時候加載本地JS)

needLoadJSPOST = true

// 創建WKWebView

webView = WKWebView(frame: UIScreen.mainScreen().bounds)

//設置代理

webView.navigationDelegate = self

// 獲取JS路徑

let path = NSBundle.mainBundle().pathForResource("JSPOST", ofType: "html")

// 獲得html內容

do {

    

    let html = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)

    // 加載js

    webView.loadHTMLString(html, baseURL: NSBundle.mainBundle().bundleURL)

} catch { }

// 將WKWebView添加到當前View

view.addSubview(webView)

 

這段代碼就相當於把工程中的JavaScript腳本加載到WKWebView中了,后面就是看怎么用了。(請注意換成您的文件名)

 

 

Native調用JavaScript腳本並傳入參數來完成POST請求

還記得 WKWebView和JavaScript的交互這一節嘛?現在該Native調用JavaScript了,如果忘記了,請往前翻溫故一下:- webView:didFinishNavigation:代理表明頁面已經加載完成,我們在這里操作,下面上代碼:

OC代碼:

// 加載完成的代理方法

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {

    // 判斷是否需要加載(僅在第一次加載)

    if (self.needLoadJSPOST) {

        // 調用使用JS發送POST請求的方法

        [self postRequestWithJS];

        // 將Flag置為NO(后面就不需要加載了)

        self.needLoadJSPOST = NO;

    }

}

 

// 調用JS發送POST請求

- (void)postRequestWithJS {

    // 發送POST的參數

    NSString *postData = @"\"username\":\"aaa\",\"password\":\"123\"";

    // 請求的頁面地址

    NSString *urlStr = @"http://www.postexample.com";

    // 拼裝成調用JavaScript的字符串

    NSString *jscript = [NSString stringWithFormat:@"post('%@', {%@});", urlStr, postData];

 

    // NSLog(@"Javascript: %@", jscript);

    // 調用JS代碼

    [self.webView evaluateJavaScript:jscript completionHandler:^(id object, NSError * _Nullable error) {

    

    }];

}

 

 

Swift代碼:

// 加載完成的代理方法

func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {

    // 判斷是否需要加載(僅在第一次加載)

    if needLoadJSPOST {

        // 調用使用JS發送POST請求的方法

        postRequestWithJS()

        // 將Flag置為NO(后面就不需要加載了)

        needLoadJSPOST = false

    }

}

// 調用JS發送POST請求

func postRequestWithJS() {

    // 發送POST的參數

    let postData = "\"username\":\"aaa\",\"password\":\"123\""

    // 請求的頁面地址

    let urlStr = "http://www.postexample.com"

    // 拼裝成調用JavaScript的字符串

    let jscript = "post('\(urlStr)', {\(postData)});"

    // 調用JS代碼

    webView.evaluateJavaScript(jscript) { (object, error) in

        

    }

}

 

好了,到目前為止你的請求就發出去了。相信后面的版本會解決這個問題,但是現在你要用的話也得有辦法,誰讓已經入了Apple的坑呢,誰讓UIWebView太不給力了呢.

 

 

 

寫在最后:

當時選擇WKWebView就是為了提高性能,但是沒有想到遇到這么多坑,從看iOS 9才解決了iOS 8無法加載本地樣式的問題,有時候蘋果解決問題的速度還有略慢的,到現在POST請求參數都發不出去也真是不應該。不過沒辦法,先解決了,說不定iOS 10 出來之后解決了呢。(我雖然有iOS 10的設備,但是我還沒有測試,感興趣的小伙伴們可以試試)。大家如果有什么問題,歡迎留言提問。謝謝支持!

 

作者:winann

鏈接:https://www.jianshu.com/p/403853b63537

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM