mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
196 lines
5.5 KiB
JavaScript
196 lines
5.5 KiB
JavaScript
// import needle from 'needle'
|
|
// import progress from 'request-progress'
|
|
import BackgroundTimer from 'react-native-background-timer'
|
|
import { debugRequest } from './env'
|
|
import { requestMsg } from './message'
|
|
import { bHh } from './music/options'
|
|
import { deflateRaw } from 'pako'
|
|
|
|
const defaultHeaders = {
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
|
|
}
|
|
// var proxyUrl = "http://" + user + ":" + password + "@" + host + ":" + port;
|
|
// var proxiedRequest = request.defaults({'proxy': proxyUrl});
|
|
|
|
|
|
/**
|
|
* 请求超时自动重试
|
|
* @param {*} url
|
|
* @param {*} options
|
|
*/
|
|
export const httpFetch = (url, options = { method: 'get' }) => {
|
|
const requestObj = fetchData(url, options)
|
|
return {
|
|
promise: requestObj.request.catch(err => {
|
|
console.log('出错', err.message)
|
|
switch (err.message) {
|
|
case 'socket hang up':
|
|
return Promise.reject(new Error(requestMsg.unachievable))
|
|
case 'Aborted':
|
|
return Promise.reject(new Error(requestMsg.timeout))
|
|
case 'Network request failed':
|
|
return Promise.reject(new Error(requestMsg.notConnectNetwork))
|
|
default:
|
|
return Promise.reject(err)
|
|
}
|
|
}),
|
|
cancelHttp() {
|
|
requestObj.abort()
|
|
},
|
|
}
|
|
}
|
|
|
|
/**
|
|
* http get 请求
|
|
* @param {*} url 地址
|
|
* @param {*} options 选项
|
|
* @param {*} callback 回调
|
|
* @return {Number} index 用于取消请求
|
|
*/
|
|
export const httpGet = (url, options, callback) => {
|
|
if (typeof options === 'function') {
|
|
callback = options
|
|
options = {}
|
|
}
|
|
const requestObj = fetchData(url, { ...options, method: 'get' })
|
|
requestObj.request.then(resp => {
|
|
callback(null, resp, resp.body)
|
|
}).catch(err => {
|
|
debugRequest && console.log(JSON.stringify(err))
|
|
callback(err, null, null)
|
|
})
|
|
|
|
return () => {
|
|
requestObj.abort()
|
|
}
|
|
}
|
|
|
|
/*
|
|
const fetchWithTimeout = (resource, options) => {
|
|
const { timeout = 8000 } = options
|
|
|
|
const controller = new global.AbortController()
|
|
const id = BackgroundTimer.setTimeout(() => controller.abort(), timeout)
|
|
|
|
return {
|
|
request: global.fetch(resource, {
|
|
...options,
|
|
signal: controller.signal,
|
|
}).then(response => {
|
|
BackgroundTimer.clearTimeout(id)
|
|
return response
|
|
}),
|
|
abort() {
|
|
controller.abort()
|
|
},
|
|
}
|
|
} */
|
|
|
|
|
|
const handleDeflateRaw = data => new Promise((resolve, reject) => {
|
|
resolve(Buffer.from(deflateRaw(data)))
|
|
// deflateRaw(data, (err, buf) => {
|
|
// if (err) return reject(err)
|
|
// resolve(buf)
|
|
// })
|
|
})
|
|
|
|
const regx = /(?:\d\w)+/g
|
|
|
|
const handleRequestData = async(url, {
|
|
method = 'get',
|
|
headers = {},
|
|
format = 'json',
|
|
cache = 'no-store',
|
|
...options
|
|
}) => {
|
|
// console.log(url, options)
|
|
headers = Object.assign({
|
|
Accept: 'application/json',
|
|
}, headers)
|
|
options.cache = cache
|
|
if (method.toLocaleLowerCase() === 'post' && !headers['Content-Type']) {
|
|
if (options.form) {
|
|
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
const formBody = []
|
|
for (let [key, value] of Object.entries(options.form)) {
|
|
let encodedKey = encodeURIComponent(key)
|
|
let encodedValue = encodeURIComponent(value)
|
|
formBody.push(`${encodedKey}=${encodedValue}`)
|
|
}
|
|
options.body = formBody.join('&')
|
|
delete options.form
|
|
} else if (options.formData) {
|
|
headers['Content-Type'] = 'multipart/form-data'
|
|
const formBody = []
|
|
for (let [key, value] of Object.entries(options.form)) {
|
|
let encodedKey = encodeURIComponent(key)
|
|
let encodedValue = encodeURIComponent(value)
|
|
formBody.push(`${encodedKey}=${encodedValue}`)
|
|
}
|
|
options.body = options.formData
|
|
delete options.formData
|
|
} else {
|
|
headers['Content-Type'] = 'application/json'
|
|
}
|
|
}
|
|
if (headers['Content-Type'] === 'application/json' && options.body) {
|
|
options.body = JSON.stringify(options.body)
|
|
}
|
|
if (headers[bHh]) {
|
|
let s = Buffer.from(bHh, 'hex').toString()
|
|
s = s.replace(s.substr(-1), '')
|
|
s = Buffer.from(s, 'base64').toString()
|
|
const v = process.versions.app.split('-')[0].split('.').map(n => n.length < 3 ? n.padStart(3, '0') : n).join('')
|
|
const v2 = process.versions.app.split('-')[1] || ''
|
|
headers[s] = !s || `${(await handleDeflateRaw(Buffer.from(JSON.stringify(`${url}${v}`.match(regx), null, 1).concat(v)).toString('base64'))).toString('hex')}&${parseInt(v)}${v2}`
|
|
delete headers[bHh]
|
|
}
|
|
|
|
return {
|
|
...options,
|
|
method,
|
|
headers: Object.assign({}, defaultHeaders, headers),
|
|
}
|
|
}
|
|
|
|
const fetchData = (url, { timeout = 15000, ...options }) => {
|
|
console.log('---start---', url)
|
|
|
|
const controller = new global.AbortController()
|
|
const id = BackgroundTimer.setTimeout(() => controller.abort(), timeout)
|
|
|
|
return {
|
|
request: handleRequestData(url, options).then(options => {
|
|
return global.fetch(url, {
|
|
...options,
|
|
signal: controller.signal,
|
|
}).then(response => {
|
|
BackgroundTimer.clearTimeout(id)
|
|
return response
|
|
}).then(resp => resp.text().then(text => {
|
|
// console.log(options, headers, text)
|
|
return {
|
|
headers: resp.headers.map,
|
|
body: text,
|
|
statusCode: resp.status,
|
|
url: resp.url,
|
|
ok: resp.ok,
|
|
}
|
|
})).then(resp => {
|
|
try {
|
|
resp.body = JSON.parse(resp.body)
|
|
} catch (_) {
|
|
}
|
|
return resp
|
|
}).catch(err => {
|
|
// console.log(err, err.code, err.message)
|
|
return Promise.reject(err)
|
|
})
|
|
}),
|
|
abort() {
|
|
controller.abort()
|
|
},
|
|
}
|
|
}
|