国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

高程3總結#第21章Ajax與Comet

MudOnTire / 458人閱讀

摘要:頁面發(fā)起一個到服務器的請求,然后服務器一直保持連接打開,直到有數據可發(fā)送。

Ajax與Comet XMLHttpRequest對象

IE5是第一款引入XHR對象的瀏覽器,在IE5中,XHR對象是通過MSXML庫中的一個ActiveX對象實現的

//適用于 IE7 之前的版本
function createXHR(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i, len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//跳過
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}

這個函數會盡力根據IE中可用的MSXML庫的情況創(chuàng)建最新版本的XHR對象

IE7+、Firefox、Opera、Chrome、Safari都支持原生的XHR對象,這些瀏覽器中創(chuàng)建XHR對象,可以使用XMLHttpRequest構造函數

var xhr=new XMLHttpRequest();

如果還必須要支持IE的更早版本,可以在createHXR()函數中加入對原生XHR對象的支持

function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
  return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined"){
  if (typeof arguments.callee.activeXString != "string"){
    var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                    "MSXML2.XMLHttp"],
        i, len;
    for (i=0,len=versions.length; i < len; i++){
      try {
        new ActiveXObject(versions[i]);
        arguments.callee.activeXString = versions[i];
        break;
      } catch (ex){
        //跳過
      }
    }
  }
  return new ActiveXObject(arguments.callee.activeXString);
} else {
  throw new Error("No XHR object available.");
}
}

這個函數中新增的代碼首先檢測原生XHR對象是否存在,如果存在則返回它的新實例,如果原生對象不存在,則檢測ActiveX對象,如果這兩種對象都不存在,就拋出一個錯誤,然后就可以使用下面的代碼在所有瀏覽器中創(chuàng)建XHR對象了

var xhr=createXHR();

XHR的用法

在使用XHR對象時,要調用的第一個方法是open(),接收3個參數:要發(fā)送的請求的類型(get或者post)、請求的URL和表示是否異步發(fā)送請求的布爾值

xhr.open("get","example.php",false);

這行代碼會啟動一個針對example.php的GET請求

URL相對于執(zhí)行代碼的當前頁面

open()方法并不會真正發(fā)送請求,而是啟動一個請求以備發(fā)送

要想發(fā)送特定的請求,調用send()方法

xhr.open("get","example.txt",false);
xhr.send(null);

send()方法接收一個參數,要作為請求主體發(fā)送的數據,如果不需要通過請求主體發(fā)送數據,必須傳入null

響應的數據會自動填充XHR對象的屬性

responseText,作為響應主體被返回的文本

responseXML,如果響應的內容類型是"text/xml"或"application/xml",這個屬性中將保存包含著響應數據的XML DOM文檔

status,響應的HTTP狀態(tài)

statusText,HTTP狀態(tài)的說明

XHR對象的readyState屬性表示請求響應過程的當前活動階段

0,未初始化,尚未調用open()方法

1,啟動,已經調用open()方法,但尚未調用send()方法

2,發(fā)送,已經調用send()方法,但尚未接收到響應

3,接收,已經接收到部分響應數據

4,完成,已經接收到全部響應數據,而且已經可以在客戶端使用了

必須在調用open()之前指定onreadystatechange事件處理程序才能確保跨瀏覽器兼容性

var xhr = createXHR();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("get", "example.txt", true);
xhr.send(null);

在接收到響應之前還可以調用abort()方法來取消異步請求

HTTP頭部信息

在發(fā)送XHR請求的同時,還會發(fā)送下列頭部信息

Accept,瀏覽器能夠處理的內容類型

Accept-Charset,瀏覽器能夠顯示的字符集

Accept-Encoding,瀏覽器能夠處理的壓縮編碼

Accept-Language,瀏覽器當前設置的語言

Connection,瀏覽器與服務器之間連接的類型

Cookie,當前頁面設置的任何Cookie

Host,發(fā)出請求的頁面所在的域

Referer,發(fā)出請求的頁面的URI

User-Agent,瀏覽器的用戶代理字符串

setRequestHeader()方法,可以設置自定義的請求頭部信息,這個方法接收兩個參數:頭部字段名稱和頭部字段的值。要成功發(fā)送頭部信息,必須在調用open()方法之后且調用send()方法之前調用setRequestHeader()

var xhr = createXHR();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("get", "example.php", true);
xhr.setRequestHeader("MyHeader", "MyValue");
xhr.send(null);

GET請求

GET是最常見的請求類型,最常用于向服務器查詢某些信息,必要時可以將查詢字符串參數追加到URI的末尾,以便將信息發(fā)送給服務器

使用GET請求經常會發(fā)生一個錯誤,就是查詢字符串的格式問題。

查詢字符串中每個參數的名稱和值都必須使用encodeURIComponent()進行編碼,然后才能放到URL的末尾,而且所有的名-值對都必須由&分隔

xhr.open("get","example.php?name1=value1&name2=value2",true)

向現有URL的末尾添加查詢字符串參數

function addURLParam(url, name, value) {
  url += (url.indexOf("?") == -1 ? "?" : "&");
  url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
  return url;
}

addURLParam()函數接收3個參數:要添加參數的URL、參數的名稱和參數的值

POST請求

POST請求,通常用于向服務器發(fā)送應該被保存的數據

function submitData(){
  var xhr = createXHR();
  xhr.onreadystatechange = function(){
    if (xhr.readyState == 4){
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
        alert(xhr.responseText);
      } else {
        alert("Request was unsuccessful: " + xhr.status);
      }
    }
  };
  xhr.open("post", "postexample.php", true);
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  var form = document.getElementById("user-info");
  xhr.send(serialize(form));
}

XMLHttpRequest 2級 FormData

FormData為序列化表單以及創(chuàng)建與表單格式相同的數據,提供了便利

var data=new FormData();
data.append("name","Nicholas");

這個append()方法接收兩個參數,鍵和值

創(chuàng)建了FormData的實例后,可以將它直接傳給XHR的send()方法

var xhr = createXHR();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("post","postexample.php", true);
var form = document.getElementById("user-info");
xhr.send(new FormData(form));

超時設定

IE8為XHR對象添加了一個timeout屬性,表示請求在等待響應多少毫秒之后就會終止,在給timeout設置一個數值后,如果在規(guī)定的時間內瀏覽器還沒有接收到響應,那么就會觸發(fā)timeout事件,進而會調用ontimeout事件處理程序

var xhr = createXHR();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    try {
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
        alert(xhr.responseText);
      } else {
        alert("Request was unsuccessful: " + xhr.status);
      }
    } catch (ex){
      //假設由 ontimeout 事件處理程序處理
    }
  }
};
xhr.open("get", "timeout.php", true);
xhr.timeout = 1000; // 將超時設置為 1  秒鐘(僅適用于 IE8+ )
xhr.ontimeout = function(){
  alert("Request did not return in a second.");
};
xhr.send(null);

overrideMimeType()方法

Firefox最早引入了overrideMimeType()方法,用于重寫XHR響應的MIME類型

通過調用overrideMimeType()方法,可以保證把響應當做XML而非純文本來處理

var xhr = createXHR();
xhr.open("get", "text.php", true);
xhr.overrideMimeType("text/xml");
xhr.send(null);

進度事件

6個進度事件

loadstart,在接收到響應數據的第一個字節(jié)時觸發(fā)

progress,在接收響應期間持續(xù)不斷地觸發(fā)

error,在請求發(fā)生錯誤時觸發(fā)

abort,在因為調用abort()方法而終止連接時觸發(fā)

load,在接收到完整的響應數據時觸發(fā)

loadend,在通信完成或者觸發(fā)error、abort或load事件后觸發(fā)

load事件
var xhr = createXHR();
xhr.onload = function(){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
  alert(xhr.responseText);
} else {
  alert("Request was unsuccessful: " + xhr.status);
}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);
progress事件
var xhr = createXHR();
xhr.onload = function(event){
if ((xhr.status >= 200 && xhr.status < 300) ||
    xhr.status == 304){
  alert(xhr.responseText);
} else {
  alert("Request was unsuccessful: " + xhr.status);
}
};
xhr.onprogress = function(event){
var divStatus = document.getElementById("status");
if (event.lengthComputable){
  divStatus.innerHTML = "Received " + event.position + " of " +
    event.totalSize +" bytes";
}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);

為確保正常執(zhí)行,必須在調用open()方法之前添加onprogress事件處理程序

跨源資源共享

CORS,跨資源共享,定義了在必須訪問跨源資源時,瀏覽器遠服務器應該如何溝通。CORS基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功還是應該失敗

IE對CORS的實現

微軟在IE8中引入了XDR類型,這個對象與XHR類型,但是能實現安全可靠的跨域通信

cookie不會隨請求發(fā)布,也不會隨響應返回

只能設置請求頭部信息中的Content-Type字段

不能訪問響應頭部信息

只支持GET和POST請求

XDR對象的使用方法與XHR對象非常相似,也是創(chuàng)建一個XDomainRequest的實例,調用open()方法,再調用send()方法,與XHR對象的open()方法不同,XDR對象的open()方法只接收2個參數:請求類型和URL

所有XDR請求都是異步執(zhí)行的,不能用它來創(chuàng)建同步請求,請求返回之后,會觸發(fā)load事件,響應的數據也會保存在responseText屬性中

var xdr = new XDomainRequest();
xdr.onload = function(){
  alert(xdr.responseText);
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null)

請求返回前調用abort()方法可以終止請求

xdr.abort();//終止請求

與XHR一樣,XDR對象也支持timeout屬性以及ontimeout事件處理程序

var xdr = new XDomainRequest();
xdr.onload = function(){
  alert(xdr.responseText);
};
xdr.onerror = function(){
  alert("An error occurred.");
};
xdr.timeout = 1000;
xdr.ontimeout = function(){
  alert("Request took too long.");
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null);

為支持POST請求,XDR對象提供了contentType屬性,用來表示發(fā)送數據的格式

var xdr = new XDomainRequest();
xdr.onload = function(){
  alert(xdr.responseText);
};
xdr.onerror = function(){
  alert("An error occurred.");
};
xdr.open("post", "http://www.somewhere-else.com/page/");
xdr.contentType = "application/x-www-form-urlencoded";
xdr.send("name1=value1&name2=value2");

其他瀏覽器對CORS的實現

要請求位于另一個域中的資源,使用標準的XHR對象并在open()方法中傳入絕對URL

var xhr = createXHR();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("get", "http://www.somewhere-else.com/page/", true);
xhr.send(null);

安全限制

不能使用setRequsetHeader()設置自定義頭部

不能發(fā)送和接收cookie

調用getAllResponseHeaders()方法總會返回空字符串

Preflighted Requests

通過Preflighted Request的透明服務器驗證機制支持開發(fā)人員使用自定義的頭部、GET和POST之外的方法,以及不同類型的主體內容

這種請求使用OPITONS方法,發(fā)送下列頭部

Origin,與簡單的請求相同

Access-Control-Method,請求自身使用的方法

Access-Control-Headers,自定義的頭部信息,多個頭部以逗號分隔

Origin: http://www.nczonline.net
Access-Control-Request-Method: POST
Access-Control-Request-Headers: NCZ

服務器可以決定是否允許這種類型的請求,服務器在響應中發(fā)送如下頭部與瀏覽器進行溝通

Access-Control-Allow-Origin,與簡單的請求相同

Access-Control-Allow-Methods,允許的方法,多個方法以逗號分隔

Access-Control-Allow-Headers,允許的頭部,多個頭部以逗號分隔

Access-Control-Max-Age,應該將這個Preflight請求緩存多長時間,以秒表示

Access-Control-Allow-Origin: http://www.nczonline.net
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: NCZ
Access-Control-Max-Age: 1728000

帶憑據的請求

通過將withCredentials屬性設置為true,可以指定某個請求應該發(fā)送憑據

Access-Control-Allow-Credentials:true

如果發(fā)送的是帶憑據的請求,但服務器的響應中沒有包含這個頭部,那么瀏覽器就不會把響應交給JavaScript,于是responseText中將是空字符串,status的值為0,而且會調用onerror()事件處理程序

跨瀏覽器的CORS
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
  xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
  vxhr = new XDomainRequest();
  xhr.open(method, url);
} else {
  xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.somewhere-else.com/page/");
if (request){
request.onload = function(){
  //對 request.responseText 進行處理
};
request.send();
}

Firefox、Safari和Chrome中的XMLHttpRequest對象與IE中的XDomainRequest對象類似,都提供了夠用的接口,這兩個對象共同的屬性方法如下

abort(),用于停止正在進行的請求

onerror(),用于替代onreadystatechange檢測錯誤

onload(),用于替代onreadystatechange檢測成功

responseText(),用于取得響應內容

send(),用于發(fā)送請求

其他跨域技術 圖像Ping

一個網頁可以從任何網頁中加載圖像,不用擔心跨域不跨域

通過圖像Ping,瀏覽器得不到任何具體的數據,但通過偵聽load和error事件,它能知道響應什么時候接收到的

var img = new Image();
img.onload = img.onerror = function(){
  alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";

圖像Ping最常用于跟蹤用戶點擊頁面或動態(tài)廣告曝光次數,圖像Ping有兩個主要的缺點,一是只能發(fā)送GET請求,二是無法訪問服務器的響應文本。因此圖像Ping只能用于瀏覽器與服務器間的單向通信

JSONP

JSONP由兩部分組成:回調函數和數據,回調函數是當響應到來時應該在頁面中調用的函數,回調函數的名字一般是在請求中指定的,而數據就是傳入回調函數中的JSON數據

function handleResponse(response){
  alert("You’re at IP address " + response.ip + ", which is in " +
        response.city + ", " + response.region_name);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

優(yōu)點在于能夠直接訪問響應文本,支持在瀏覽器與服務器之間雙向通信

Comet

兩種實現Comet的方式

長輪詢

短輪詢時間線

長輪詢把短輪詢顛倒了一下。頁面發(fā)起一個到服務器的請求,然后服務器一直保持連接打開,直到有數據可發(fā)送。發(fā)送完數據之后,瀏覽器關閉連接,隨即又發(fā)起一個到服務器的新請求,這一過程在頁面打開期間一直持續(xù)不斷

在頁面的整個生命周期內只使用一個HTTP連接,具體來說就是瀏覽器向服務器發(fā)送一個請求,而服務器保持連接打開,然后周期性的向瀏覽器發(fā)送數據

function createStreamingClient(url, progress, finished){
  var xhr = new XMLHttpRequest(),
      received = 0;
  xhr.open("get", url, true);
  xhr.onreadystatechange = function(){
    var result;
    if (xhr.readyState == 3){
      //只取得最新數據并調整計數器
      result = xhr.responseText.substring(received);
      received += result.length;
      //調用 progress 回調函數
      progress(result);
    } else if (xhr.readyState == 4){
      finished(xhr.responseText);
    }
  };
  xhr.send(null);
  return xhr;
}
var client = createStreamingClient("streaming.php", function(data){
  alert("Received: " + data);
}, function(data){
  alert("Done!");
});

這個createStreamingClient()函數接收三個參數:要連接的URL、在接收到數據時調用的函數以及關閉連接時調用的函數

服務器發(fā)送事件

SSE是圍繞只讀Comet交互推出的API或者模式

var source=new EventSource("myevents.php");

EventSource的實例有一個readyState屬性,值為0表示正連接到服務器,值為1表示打開了連接,值為2表示關閉了連接

另外還有三個事件

open,在建立連接時觸發(fā)

message,在從服務器接收到新事件時觸發(fā)

error,在無法建立連接時觸發(fā)

Web Sockets

Web Sockets的目標是在一個多帶帶的持久連接上提供全雙工、雙向通信

要創(chuàng)建Web Socket,先實例一個WebSocket對象并傳入要連接的URL

var socket = new WebSocket("ws://www.example.com/server.php");

實例化WebSocket對象后,瀏覽器會馬上嘗試創(chuàng)建連接,與XHR類似,WebSocket也有一個表示當前狀態(tài)的readyState屬性,這個屬性的值與XHR并不相同

WebSocket.OPENING(0),正在建立連接

WebSocket.OPEN(1),已經建立連接

WebSocket.CLOSING(2),正在關閉連接

WebSocket.CLOSE(3),已經關閉連接

WebSocket沒有readystatechange事件,不過有其他事件,對應著不同的狀態(tài),readyState的值永遠從0開始

要關閉Web Socket連接,可以在任何時候調用close()方法

socket.close();

調用close()之后,readyState的值立即變?yōu)?,而關閉連接后就會變成3

使用send()方法并傳入任意字符串

var socket = new WebSocket("ws://www.example.com/server.php");
socket.send("Hello world!");
//將數據序列化為JSON字符串,然后發(fā)送到服務器
var message = {
  time: new Date(),
  text: "Hello world!",
  clientId: "asdfp8734rew"
};
socket.send(JSON.stringify(message));
//當服務器收到消息時,WebSocket對象就會觸發(fā)message事件,這個message事件與其他傳遞消息的協議類似,也是把返回的數據保存在event.data屬性中
socket.onmessage = function(event){
  var data = event.data;
  //處理數據
};

其他事件

open,在成功建立連接時觸發(fā)

error,在發(fā)生錯誤時觸發(fā),連接不能持續(xù)

close,在連接關閉時觸發(fā)

var socket = new WebSocket("ws://www.example.com/server.php");
socket.onopen = function(){
  alert("Connection established.");
};
socket.onerror = function(){
  alert("Connection error.");
};
socket.onclose = function(){
  alert("Connection closed.");
};

SSE與Web Sockets

考慮是使用 SSE 還是使用 Web Sockets 時,可以考慮如下幾個因素。

首先,你是否有自由度建立和維護 Web Sockets服務器?因為 Web Socket 協議不同于 HTTP,所以現有服務器不能用于 Web Socket 通信。SSE 倒是通過常規(guī) HTTP 通信,因此現有服務器就可以滿足需求。

第二個要考慮的問題是到底需不需要雙向通信。如果用例只需讀取服務器數據(如比賽成績),那么 SSE 比較容易實現。如果用例必須雙向通信(如聊天室),那么 Web Sockets 顯然更好。在不能選擇 Web Sockets 的情況下,組合 XHR 和 SSE 也是能實現雙向通信的。

安全

為確保通過 XHR 訪問的 URL 安全,通行的做法就是驗證發(fā)送請求者是否有權限訪問相應的資源

要求以 SSL 連接來訪問可以通過 XHR 請求的資源。

要求每一次請求都要附帶經過相應算法計算得到的驗證碼。請注意,下列措施對防范 CSRF 攻擊不起作用。

要求發(fā)送 POST 而不是 GET 請求——很容易改變。

檢查來源 URL 以確定是否可信——來源記錄很容易偽造。

基于 cookie 信息進行驗證——同樣很容易偽造

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98093.html

相關文章

  • AjaxComet-JavaScript高級程序設計21讀書筆記(1)

    摘要:技術的核心是對象即。收到響應后,響應的數據會自動填充對象的屬性,相關的屬性有作為響應主體被返回的文本。收到響應后,一般來說,會先判斷是否為,這是此次請求成功的標志。中的版本會將設置為,而中原生的則會將規(guī)范化為。會在取得時報告的值為。 Ajax(Asynchronous Javascript + XML)技術的核心是XMLHttpRequest對象,即: XHR。雖然名字中包含XML,但...

    imingyu 評論0 收藏0
  • 高程3總結#20JSON

    摘要:語法語法可以表示三種類型的值簡單值使用與相同的語法,可以在中表示字符串數值布爾值和。對象對象作為一種復雜數據類型,表示的是一組無序的鍵值對兒。如果字符串長度超過了個,結果中將只出現前個字符。 JSON 語法 JSON語法可以表示三種類型的值 簡單值:使用與 JavaScript 相同的語法,可以在 JSON 中表示字符串、數值、布爾值和 null 。但 JSON 不支持 JavaS...

    Hwg 評論0 收藏0
  • 高程3總結#3基本概念

    摘要:基本概念語法區(qū)分大小寫,中的一切變量函數名和操作符都區(qū)分大小寫。要將一個值轉換成對應的值,可以調用類型包括整數和浮點數值,基本數值字面量格式是十進制整數,除了十進制外還有八進制十六進制。八進制第一位必須是,十六進制第一位必須是。 基本概念 語法 區(qū)分大小寫,ECMAScript中的一切(變量、函數名和操作符)都區(qū)分大小寫。函數名不能使用typeof,因為它是一個關鍵字,但typeOf...

    Rindia 評論0 收藏0
  • 高程3總結#11DOM擴展

    摘要:操作類名時可以通過屬性添加刪除和替換類名。如果將可選的參數設置為,則表示盡量將元素顯示在視口中部垂直方向。將元素的內容滾動指定的頁面高度,具體高度由元素的高度決定。 DOM擴展 選擇符API querySelector()方法 querySelector()方法接收一個CSS選擇符,返回與該模式匹配的第一個元素,如果沒有找到匹配的元素,返回null //取得body元素 var b...

    cucumber 評論0 收藏0
  • 高程3總結#17錯誤處理調試

    錯誤處理與調試 錯誤處理 try-catch語句 try{ //可能會導致錯誤的代碼 }catch(error){ //在錯誤發(fā)生時怎么處理 } 發(fā)生錯誤時可以顯示瀏覽器給出的信息 try{ window.someNonexistentFunction(); }catch(error){ alert(error.message); } 在try-catch語句中是可選的,但...

    fizz 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<