JS之AJAX-响应解码

通过AJAX接收到的响应主体类型可以是多种形式的,包括字符串String、ArrayBuffer对象、二进制Blob对象、JSON对象、JavaScirpt文件及表示XML文档的Document对象等。下面将针对不同的主体类型,进行相应的响应解码

属性

responseText

responseText属性返回从服务器接收到的字符串,如果请求不成功或者数据不完整,则返回null。该属性只读

如果服务器返回的数据格式是JSON、字符串、JavaScript都可以使用responseText属性

response

response属性返回从服务器接收到的数据体,它的类型可以是ArrayBuffer、Blob、Document、JSON对象、或者一个字符串,具体类型由responseType属性的值决定。如果请求不成功或者数据不完整,则返回null。该属性只读

responseType

responseType属性用于指定服务器返回数据的类型(response类型),取值如下

'':             字符串(默认值)
'arraybuffer':  ArrayBuffer对象
'blob':         Blob对象
'document':     Document对象
'json':         JSON对象
'text':         字符串

responseXML

responseXML属性返回从服务器接收到的Document对象,如果本次请求没有成功或者数据不完整,或者不能被解析为XML或HTML,该属性等于null。该属性只读

字符串

如果服务器返回的结果是一个字符串,直接使用responseText属性解析即可

接下来的所有示例会用到前文封装的AJAX函数

function AJAX(obj) {
  var method = obj.method || 'GET',
    headers = obj.headers || {},
    data = obj.data || {},
    url = obj.url || '';
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if(xhr.readyState == 4) {
      if((xhr.status >= 200 && xhr.readyState < 300) || xhr.status == 304) {
        obj.callback && obj.callback(xhr.responseText)
      }
    }
  }
  if((obj.method).toUpperCase() == 'GET') {
    // 编码
    for(var key in data) {
      url += (url.indexOf("?") == -1 ? "?" : "&");
      url += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]);
    }
    // url += '&' + Date.now(); // 随机时间戳,防止请求缓存
  }
  xhr.open(method, url, true);
  // 设置header
  for(var header in headers) {
    xhr.setRequestHeader(header, headers[header]);
  }
  if((obj.method).toUpperCase() == 'GET') {
    xhr.send(null);
  }else{
    xhr.send(JSON.stringify(data));
  }
}

前端示例

<button id="btn">按钮</button>
<script>
btn.onclick = function() {
  AJAX({
    url: '/api/test',
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    },
    callback: function(ret) {
      console.log(ret)
    }
  })
}
</script>

后端示例

const fs = require('fs');
const path = require('path');
const express = require('express');
const app = express();
app.use(express.static(path.resolve(__dirname, './dist')))

app.get('/api/test', function(req, res) {
  res.send('hello world')
})

app.get('*', function(req, res) {
  const html = fs.readFileSync(path.resolve(__dirname, './index.html'), 'utf-8')
  res.send(html)
})
app.listen(3030);

结果

JSON

如果服务器返回的结果是一个JSON字符串,同样可以使用responseText属性解析

前端示例

btn.onclick = function() {
  AJAX({
    url: '/api/test',
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    },
    callback: function(ret) {
      console.log(JSON.parse(ret))
    }
  })
}

后端示例

app.get('/api/test', function(req, res) {
  res.send({
    name: 'wmui',
    age: 18
  })
})

结果

JS文件

如果服务器返回了JS文件,仍然是使用responseText来接收数据,但要使用eval()来执行代码

前端示例

  1. 在dist目录下建一个test.js文件,内容如下:
function foo() {
  console.log('hello world')
}
  1. 发送请求
btn.onclick = function() {
  AJAX({
    url: '/test.js',
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    },
    callback: function(ret) {
      eval(ret)
      foo()
    }
  })
}

结果

XML

XML在JSON出现之前,是网络上常用的数据传输格式,但由于其格式较笨重,所以用的较少。接收XML文档时,使用responseXML来对数据进行解析

前端示例

  1. 在dist目录下建一个test.xml文件,内容如下:
<CATALOG data-livestyle-extension="available">
<CD>
  <TITLE>JS</TITLE>
  <DES>脚本语言</DES>
</CD>
<CD>
  <TITLE>CSS</TITLE>
  <DES>层叠样式表</DES>
</CD>
<CD>
  <TITLE>HTML</TITLE>
  <DES>超文本标记语言</DES>
</CD>
</CATALOG>
  1. 把AJAX函数中的obj.callback && obj.callback(xhr.responseText)改成obj.callback && obj.callback(xhr.responseXML)

  2. 发送请求

btn.onclick = function() {
  AJAX({
    url: '/test.xml',
    method: 'GET',
    headers: {
      'Content-Type': 'application/json'
    },
    callback: function(ret) {
      console.log(ret)
    }
  })
}

结果

blob

在JavaScript中,Blob通常表示二进制数据。在实际Web应用中,Blob更多是图片二进制形式的上传与下载

使用AJAX接收blob数据,需要使用response来接收,并且将responseType设置为'blob'

前端示例

  1. 在dist目录下放置一张图片,比如t.png

  2. 修改AJAX方法,把obj.callback && obj.callback(xhr.responseText)改成obj.callback && obj.callback(xhr.response)

  3. 在open()方法后面设置xhr.responseType = 'blob';

  4. 发送请求

<div id="result"></div>
<button id="btn">按钮</button>
<script>
btn.onclick = function() {
  AJAX({
    url: '/t.png',
    method: 'GET',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    callback: function(ret) {
      var img = document.createElement('img');
      img.onload = function() {
// 说明:图片呈现到页面后,执行revoke,其他引用这个blob url的地方就无效了
        URL.revokeObjectURL(img.src);
      }
      img.src = URL.createObjectURL(ret)
      if(!result.innerHTML){
        result.appendChild(img);
      }
    }
  })
}
</script>

结果

arraybuffer

arraybuffer代表储存二进制数据的一段内存,通过ajax接收到的arraybuffer,需要先将其转换为blob数据,然后才能进行操作

前端示例

  1. 在dist目录下放置一张图片,比如t.png

  2. 修改AJAX方法,把obj.callback && obj.callback(xhr.responseText)改成obj.callback && obj.callback(xhr.response)

  3. 在open()方法后面设置xhr.responseType = 'arraybuffer';

  4. 发生请求

<div id="result"></div>
<button id="btn">按钮</button>
<script>
btn.onclick = function() {
  AJAX({
    url: '/t.png',
    method: 'GET',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    callback: function(ret) {
      var img = document.createElement('img');
      img.onload = function() {
        URL.revokeObjectURL(img.src);
      }
      // 将ret作为new Blob()构造函数的参数传递,生成blob对象
      img.src = URL.createObjectURL(new Blob([ret]))
      if(!result.innerHTML){
        result.appendChild(img);
      }
    }
  })
}
</script>

结果

posted @ 2021-09-29 14:05  wmui  阅读(512)  评论(0编辑  收藏  举报