php trim rn,RN中fetch错误提示更详细

在React Native项目的开发中,发送网络请求时,有时会遇到Network

request

failed这样的错误,可能会很迷惑,通过这个错误提示,很难去判断到底是什么原因导致网络请求出错的。查看了fetch具体的实现方法后,这个时候就很容易知道问题出在哪里了。

React-Native的fetch实现方法是用XMLHttpRequest来封装实现的,而onerror的回调都会提示Network

request

failed。onerror的错误都是关于网络层的,涉及到的错误并不少,如果不区分,会给开发过程带来很多困扰,同时也不知道到底是什么错误。在项目中修改下fetch.js的onerror回调方法后,即可增加一些网络层相关的提示。

比如(一段代码示例):

'use strict';

var self = {};

(function() {

'use strict';

if (self.fetch) {

return

}

function normalizeName(name) {

if (typeof name !== 'string')

{

name = String(name)

}

if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name))

{

throw new TypeError('Invalid

character in header field name')

}

return name.toLowerCase()

}

function normalizeValue(value) {

if (typeof value !== 'string')

{

value = String(value)

}

return value

}

function Headers(headers) {

this.map = {}

if (headers instanceof Headers)

{

headers.forEach(function(value, name) {

this.append(name, value)

}, this)

} else if (headers)

{

Object.getOwnPropertyNames(headers).forEach(function(name) {

this.append(name, headers[name])

}, this)

}

}

Headers.prototype.append = function(name, value)

{

name = normalizeName(name)

value = normalizeValue(value)

var list = this.map[name]

if (!list) {

list = []

this.map[name] = list

}

list.push(value)

}

Headers.prototype['delete'] = function(name)

{

delete this.map[normalizeName(name)]

}

Headers.prototype.get = function(name)

{

var values = this.map[normalizeName(name)]

return values ? values[0] : null

}

Headers.prototype.getAll = function(name)

{

return this.map[normalizeName(name)] || []

}

Headers.prototype.has = function(name)

{

return this.map.hasOwnProperty(normalizeName(name))

}

Headers.prototype.set = function(name, value)

{

this.map[normalizeName(name)] = [normalizeValue(value)]

}

Headers.prototype.forEach = function(callback, thisArg)

{

Object.getOwnPropertyNames(this.map).forEach(function(name)

{

this.map[name].forEach(function(value) {

callback.call(thisArg, value, name, this)

}, this)

}, this)

}

function consumed(body) {

if (body.bodyUsed) {

return Promise.reject(new TypeError('Already

read'))

}

body.bodyUsed = true

}

function fileReaderReady(reader) {

return new Promise(function(resolve, reject)

{

reader.onload = function()

{

resolve(reader.result)

}

reader.onerror = function()

{

reject(reader.error)

}

})

}

function readBlobAsArrayBuffer(blob) {

var reader = new FileReader()

reader.readAsArrayBuffer(blob)

return fileReaderReady(reader)

}

function readBlobAsText(blob) {

var reader = new FileReader()

reader.readAsText(blob)

return fileReaderReady(reader)

}

var support = {

blob: typeof FileReader === 'function' && typeof Blob === 'function' && (function()

{

try {

new Blob();

return true

} catch(e) {

return false

}

})(),

formData: typeof FormData === 'function',

arrayBuffer: typeof ArrayBuffer === 'function'

}

function Body() {

this.bodyUsed = false

this._initBody = function(body)

{

this._bodyInit = body

if (typeof body === 'string')

{

this._bodyText = body

} else if (support.blob && Blob.prototype.isPrototypeOf(body))

{

this._bodyBlob = body

} else if (support.formData && FormData.prototype.isPrototypeOf(body))

{

this._bodyFormData = body

} else if (!body)

{

this._bodyText = ''

} else if (support.arrayBuffer && ArrayBuffer.prototype.isPrototypeOf(body))

{

// Only support ArrayBuffers for POST method.

// Receiving ArrayBuffers happens via Blobs, instead.

} else {

throw new Error('unsupported

BodyInit type')

}

if (!this.headers.get('content-type')) {

if (typeof body === 'string')

{

this.headers.set('content-type', 'text/plain;charset=UTF-8')

} else if (this._bodyBlob && this._bodyBlob.type)

{

this.headers.set('content-type', this._bodyBlob.type)

}

}

}

if (support.blob) {

this.blob = function() {

var rejected = consumed(this)

if (rejected) {

return rejected

}

if (this._bodyBlob) {

return Promise.resolve(this._bodyBlob)

} else if (this._bodyFormData)

{

throw new Error('could not

read FormData body as blob')

} else {

return Promise.resolve(new Blob([this._bodyText]))

}

}

this.arrayBuffer = function()

{

return this.blob().then(readBlobAsArrayBuffer)

}

this.text = function() {

var rejected = consumed(this)

if (rejected) {

return rejected

}

if (this._bodyBlob) {

return readBlobAsText(this._bodyBlob)

} else if (this._bodyFormData)

{

throw new Error('could not

read FormData body as text')

} else {

return Promise.resolve(this._bodyText)

}

}

} else {

this.text = function() {

var rejected = consumed(this)

return rejected ? rejected : Promise.resolve(this._bodyText)

}

}

if (support.formData) {

this.formData = function()

{

return this.text().then(decode)

}

}

this.json = function() {

return this.text().then(JSON.parse)

}

return this

}

// HTTP methods whose capitalization should be normalized

var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']

function normalizeMethod(method) {

var upcased = method.toUpperCase()

return (methods.indexOf(upcased) > -1) ? upcased : method

}

function Request(input, options)

{

options = options || {}

var body = options.body

if (Request.prototype.isPrototypeOf(input))

{

if (input.bodyUsed) {

throw new TypeError('Already

read')

}

this.url = input.url

this.credentials = input.credentials

if (!options.headers) {

this.headers = new Headers(input.headers)

}

this.method = input.method

this.mode = input.mode

if (!body) {

body = input._bodyInit

input.bodyUsed = true

}

} else {

this.url = input

}

this.credentials = options.credentials || this.credentials || 'omit'

if (options.headers || !this.headers)

{

this.headers = new Headers(options.headers)

}

this.method = normalizeMethod(options.method || this.method || 'GET')

this.mode = options.mode || this.mode || null

this.referrer = null

if ((this.method === 'GET' || this.method === 'HEAD') && body)

{

throw new TypeError('Body not

allowed for GET or HEAD requests')

}

this._initBody(body)

}

Request.prototype.clone = function()

{

return new Request(this)

}

function decode(body) {

var form = new FormData()

body.trim().split('&').forEach(function(bytes)

{

if (bytes) {

var split = bytes.split('=')

var name = split.shift().replace(/\+/g, ' ')

var value = split.join('=').replace(/\+/g, ' ')

form.append(decodeURIComponent(name), decodeURIComponent(value))

}

})

return form

}

function headers(xhr) {

var head = new Headers()

var pairs = xhr.getAllResponseHeaders().trim().split('\n')

pairs.forEach(function(header) {

var split = header.trim().split(':')

var key = split.shift().trim()

var value = split.join(':').trim()

head.append(key, value)

})

return head

}

Body.call(Request.prototype)

function Response(bodyInit, options)

{

if (!options) {

options = {}

}

this.type = 'default'

this.status = options.status

this.ok = this.status >= 200 && this.status 

this.statusText = options.statusText

this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers)

this.url = options.url || ''

this._initBody(bodyInit)

}

Body.call(Response.prototype)

Response.prototype.clone = function()

{

return new Response(this._bodyInit,

{

status: this.status,

statusText: this.statusText,

headers: new Headers(this.headers),

url: this.url

})

}

Response.error = function()

{

var response = new Response(null,

{status: 0, statusText: ''})

response.type = 'error'

return response

}

var redirectStatuses = [301, 302, 303, 307, 308]

Response.redirect = function(url, status)

{

if (redirectStatuses.indexOf(status) === -1)

{

throw new RangeError('Invalid

status code')

}

return new Response(null,

{status: status,

headers: {location: url}})

}

self.Headers = Headers;

self.Request = Request;

self.Response = Response;

self.fetch = function(input, init)

{

return new Promise(function(resolve, reject)

{

var request

if (Request.prototype.isPrototypeOf(input) && !init)

{

request = input

} else {

request = new Request(input,

init)

}

var xhr = new XMLHttpRequest()

function responseURL() {

if ('responseURL' in xhr)

{

return xhr.responseURL

}

// Avoid security warnings on getResponseHeader when not allowed

by CORS

if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders()))

{

return xhr.getResponseHeader('X-Request-URL')

}

return;

}

xhr.onload = function() {

var status = (xhr.status === 1223) ? 204 : xhr.status

if (status  599)

{

reject(new TypeError('Network request

failed'))

return

}

var options = {

status: status,

statusText: xhr.statusText,

headers: headers(xhr),

url: responseURL()

}

var body = 'response' in xhr ? xhr.response : xhr.responseText;

resolve(new Response(body, options))

}

xhr.onerror = function(e)

{

if(e && e.target && e.target._responseText){

return reject(new Error(e.target._responseText));

}

reject(new TypeError('Network request

failed'))

}

xhr.open(request.method, request.url, true)

if (request.credentials === 'include')

{

xhr.withCredentials = true

}

if ('responseType' in xhr && support.blob)

{

xhr.responseType = 'blob'

}

request.headers.forEach(function(value, name)

{

xhr.setRequestHeader(name, value)

})

xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)

})

}

self.fetch.polyfill = true

})();

module.exports = self;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值