request.js 2.9 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import {
2 3
  publish,
  requireNativePlugin
fxy060608's avatar
fxy060608 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
} from '../../bridge'

let requestTaskId = 0
const requestTasks = {}

const publishStateChange = res => {
  publish('onRequestTaskStateChange', res)
  delete requestTasks[requestTaskId]
}

export function createRequestTaskById (requestTaskId, {
  url,
  data,
  header,
  method = 'GET'
19 20 21 22 23 24
} = {}) {
  const stream = requireNativePlugin('stream')
  const headers = {}

  let abortTimeout
  let aborted
fxy060608's avatar
fxy060608 已提交
25
  let hasContentType = false
26 27 28 29 30 31 32 33 34 35 36
  for (const name in header) {
    if (!hasContentType && name.toLowerCase() === 'content-type') {
      hasContentType = true
      headers['Content-Type'] = header[name]
    } else {
      headers[name] = header[name]
    }
  }

  if (!hasContentType && method === 'POST') {
    headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
fxy060608's avatar
fxy060608 已提交
37
  }
Q
qiang 已提交
38

39 40
  const timeout = __uniConfig.networkTimeout.request
  if (timeout) {
41 42
    abortTimeout = setTimeout(() => {
      aborted = true
fxy060608's avatar
fxy060608 已提交
43 44 45 46 47 48
      publishStateChange({
        requestTaskId,
        state: 'fail',
        statusCode: 0,
        errMsg: 'timeout'
      })
49
    }, timeout)
fxy060608's avatar
fxy060608 已提交
50
  }
51 52
  const options = {
    method,
53
    url: url.trim(),
54 55
    // weex 官方文档有误,headers 类型实际 object,用 string 类型会无响应
    headers,
56 57 58
    type: 'text',
    // weex 官方文档未说明实际支持 timeout,单位:ms
    timeout: timeout || 6e5
59 60 61
  }
  if (method !== 'GET') {
    options.body = data
fxy060608's avatar
fxy060608 已提交
62 63
  }
  try {
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
    stream.fetch(options, ({
      status,
      data,
      headers
    }) => {
      if (aborted) {
        return
      }
      if (abortTimeout) {
        clearTimeout(abortTimeout)
      }
      const statusCode = status
      if (statusCode > 0) {
        publishStateChange({
          requestTaskId,
          state: 'success',
          data,
          statusCode,
          header: headers
        })
      } else {
        publishStateChange({
          requestTaskId,
          state: 'fail',
          statusCode,
          errMsg: 'abort'
        })
      }
    })
    requestTasks[requestTaskId] = {
      abort () {
        aborted = true
        if (abortTimeout) {
          clearTimeout(abortTimeout)
        }
        publishStateChange({
          requestTaskId,
          state: 'fail',
          statusCode: 0,
          errMsg: 'abort'
        })
      }
    }
fxy060608's avatar
fxy060608 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
  } catch (e) {
    return {
      requestTaskId,
      errMsg: 'createRequestTask:fail'
    }
  }
  return {
    requestTaskId,
    errMsg: 'createRequestTask:ok'
  }
}

export function createRequestTask (args) {
  return createRequestTaskById(++requestTaskId, args)
}

export function operateRequestTask ({
  requestTaskId,
  operationType
} = {}) {
  const requestTask = requestTasks[requestTaskId]
  if (requestTask && operationType === 'abort') {
    requestTask.abort()
    return {
      errMsg: 'operateRequestTask:ok'
    }
  }
  return {
    errMsg: 'operateRequestTask:fail'
  }
}