上節(jié)我們閱讀了stream類中的兩種方法sendhttp和fetch,這節(jié)我們繼續(xù)閱讀stream的方法。
我們應(yīng)該注意到<code>_jsonp.apply(this, _callArgs)</code>和<code>_xhr.apply(this, _callArgs)</code>這兩個(gè)方法钞速。個(gè)人建議使用xhr結(jié)合cors方法進(jìn)行跨域,因此這節(jié)主要在于分析_xhr的源碼足陨。
按照慣例叫乌,貼出_xhr的源碼
function _xhr (config, callback, progressCallback) {
const xhr = new XMLHttpRequest()
xhr.responseType = config.type
xhr.open(config.method, config.url, true)
const headers = config.headers || {}
for (const k in headers) {
xhr.setRequestHeader(k, headers[k])
}
xhr.onload = function (res) {
callback({
status: xhr.status,
ok: xhr.status >= 200 && xhr.status < 300,
statusText: xhr.statusText,
data: xhr.response,
headers: xhr.getAllResponseHeaders().split('\n')
.reduce(function (obj, headerStr) {
const headerArr = headerStr.match(/(.+): (.+)/)
if (headerArr) {
obj[headerArr[1]] = headerArr[2]
}
return obj
}, {})
})
}
if (progressCallback) {
xhr.onprogress = function (e) {
progressCallback({
readyState: xhr.readyState,
status: xhr.status,
length: e.loaded,
total: e.total,
statusText: xhr.statusText,
headers: xhr.getAllResponseHeaders().split('\n')
.reduce(function (obj, headerStr) {
const headerArr = headerStr.match(/(.+): (.+)/)
if (headerArr) {
obj[headerArr[1]] = headerArr[2]
}
return obj
}, {})
})
}
}
xhr.onerror = function (err) {
logger.error('unexpected error in _xhr for \'fetch\' API', err)
callback({
status: ERROR_STATE,
ok: false,
statusText: '',
data: '',
headers: {}
})
}
xhr.send(config.body)
}
- _xhr函數(shù)的聲明
<code>function _xhr (config, callback, progressCallback) {}</code>和<code>_xhr.apply(this, _callArgs)</code>相對(duì)應(yīng)。XX.apply(,)中嚼鹉,XX是一個(gè)函數(shù)贩汉,apply的第一個(gè)參數(shù)是指代作用域,第二個(gè)參數(shù)是XX函數(shù)的參數(shù)列表锚赤。(如果對(duì)這種方式不了解可以匹舞,查閱js相關(guān)文檔)
- xhr對(duì)象的示例化和設(shè)置處理函數(shù)
可以通過(guò)下面的代碼段看出:
const xhr = new XMLHttpRequest()
xhr.setRequestHeader(k, headers[k])
xhr.onload = function (res) {}
xhr.onprogress = function (e) {}
hr.onerror = function (err) {}
xhr.send(config.body)
這是典型的XmlHttpRequest對(duì)象的使用,XmlHttpRequest是前端開(kāi)發(fā)中使用最頻繁的一個(gè)方法线脚,可以參考百度百科
其中下面的一段代碼
headers: xhr.getAllResponseHeaders().split('\n')
.reduce(function (obj, headerStr) {
const headerArr = headerStr.match(/(.+): (.+)/)
if (headerArr) {
obj[headerArr[1]] = headerArr[2]
}
return obj
}, {})
是用來(lái)把字符串的headers變?yōu)閖s對(duì)象的的請(qǐng)求頭赐稽。數(shù)組的reduce方法可以實(shí)現(xiàn)相近的兩個(gè)元素調(diào)用同一個(gè)方法,同時(shí)返回新的對(duì)象的方法浑侥。obj是數(shù)組的前一個(gè)元素姊舵,headerStr是后一個(gè)元素。
代碼 <code>obj[headerArr[1]] = headerArr[2]</code>之所以從1開(kāi)始是因?yàn)?元素為原字符串(js 正則表達(dá)的匹配規(guī)則)锭吨。
stream到此已經(jīng)分析完畢蠢莺,下節(jié)我們分析sender.js寒匙。sender.js的路徑為:
零如。再次感謝閱讀,如有錯(cuò)誤歡迎提意見(jiàn)啊