AJAX

2020-07-22  本文已影响0人  泡杯感冒灵

题目

  1. 手写一个ajax
// GET请求
const xhr = new XMLHttpRwquest()
// true表示异步的网络请求,默认是true
xhr.open('GET','/api',true)
xhr.onreadStateChange = function(){
  if(xhr.readState === 4){
    if(xhr.status === 200){
        console.log(JSON.parse(xhr.responseText))
    }else{
        console.log(其他情况'')
    }
  }
}
xhr.send(null)


// post请求
const xhr = new XMLHttpRwquest()
xhr.open('POST','/api',true)
xhr.onreadStateChange = function(){
  if(xhr.readState === 4){
    if(xhr.status === 200){
        console.log(JSON.parse(xhr.responseText))
    }else{
        console.log(其他情况'')
    }
  }
}
const postData = {
  userName:'xiaoming',
  password:'xxx'
}
// JSON.stringify,将 JavaScript 值转换为 JSON 字符串
// 必须要转换成字符串发送,我们用其他工具,直接发送,是因为其他工具已经帮我们做了转换
xhr.send(JSON.stringify(postData))


// 结合promise
function ajax(url) {
  const p = new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url, true)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if ((xhr.status >= 200 && xhr < 300) || xhr === 304) {
          resolve(JSON.parse(xhr.responseText))
        } else if (xhr.status === 404) {
          reject(new Error('404 not found'))
        }
      }
    }
    xhr.send(null)
  })
  return p
}
ajax('/data.json')
.then(res => {console.log(res})
.cathc(err => {console.error(err)})
  1. 跨域的常用实现方式

知识点

  1. XMLHttpRequest
  1. 状态码
`readyState`是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。
  // xhr.readState  === 0  (未初始化),还未调用send方法
  // xhr.readState  === 1  (载入),已调用send方法,正在发送请求
  // xhr.readState  === 2  (载入完成),send方法执行完成,已经接受到全部响应内容
  // xhr.readState  === 3 (交互)正在解析响应内容
  // xhr.readState  === 4 (完成)响应内容解析完成,可以在客户端调用
`status`是XMLHttpRequest对象的一个属性,表示响应的HTTP状态码
// 在HTTP1.1协议下,HTTP状态码总共可分为5大类,如下表所示:
// 1xx 服务器收到请求,需要继续处理。例如101状态码,表示服务器将通知客户端使用更高版本的HTTP协议。
// 2XX 请求成功。例如200状态码,表示请求所希望的响应头或数据体将随此响应返回。
// 3XX  重定向。例如302状态码,表示临时重定向,请求将包含一个新的URL地址,客户端将对新的地址进行GET请求。
// 4XX  客户端错误。例如404状态码,表示客户端请求的资源不存在。
// 5XX  服务器错误。例如500状态码,表示服务器遇到了一个未曾预料的情况,导致了它无法完成响应,一般来说,这个问题会在程序代码出错时出现。
  1. 跨域:同源策略,跨域解决方案
什么是跨域?(同源策略)
<img src="跨域的图片地址"/>   // 可用于统计打点,可使用第三方统计服务
<link href="跨域的css地址"/>  // 可使用CDN,CDN一般都是外域
<script src="跨域的JS地址"/>  // 可使用CDN,CDN一般都是外域; 可实现JSONP
跨域的解决方式

注意:所有的跨域,都必须经过server端的允许和配合,未经server端的允许,就实现跨域,说明浏览器有漏洞,危险信号

  1. script 可以绕过跨域
  2. 服务器可以任意动态拼接数据返回
  3. 所以,script就可以获得跨域的数据,只要服务端愿意返回
// 自己写JSONP
<body>
  <p>jsonp跨域</p>
  <script>
    window.userInfo = function(data) {
      console.log(data)
    }
  </script>
  <script src="http://localhost:8002/jsonp.js?name=xxx&callabck=userInfo"></script>
</body>


// jsonp.js
userInfo(
  {name:'xiaoming'}
)


// jQuery实现JSONP
$.ajax({
  url: 'http:localhost:8002/demo.json',
  dataType: 'jsonp',   // 告诉jquery我们用jsonp
  jsonpCallback: 'callback', //callback的名字
  success: function (data) {
    console.log(data)
  }
})

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。
对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

ajax常用的插件

$.ajax({
  // 请求方式
  type: 'POST',
  // 请求的媒体类型
  contentType: "application/json;charset=UTF-8",
  // 请求地址
  url: "http://127.0.0.1/admin/list/",
  // 传送数据
  data: JSON.stringify(list),
  // 请求成功
  success: function (result) {
    console.log(result)
  },
  // 请求失败,包含具体的错误信息
  error: function (e) {
    console.log(e.status)
    console.log(e.responseText)
  }
})

fetch是一种http数据请求方式,是XMLHttpRequest的一种替代方案。fetch不是ajax的进一步封装,而是原生JS,fetch函数就是原生JS,没有使用XMLHttpRequest对象。它默认返回 promise
fetch 不会从服务端发送和接收任何cookies,除非做了设置

// fetch的第一个参数是url,第二个参数可选,是一个配置,类似于jquery
fetch('http://example.com/movies.json')
  .then(response => response.json())
  .then(data => console.log(data));


// Example POST method implementation:
async function postData(url = '', data = {}) {
  // Default options are marked with *
  const response = await fetch(url, {
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });
  return response.json(); // parses JSON response into native JavaScript objects
}

postData('https://example.com/answer', { answer: 42 })
  .then(data => {
    console.log(data); // JSON data parsed by `data.json()` call
  });
  1. 从浏览器中创建 XMLHttpRequest
  2. 从nodejs中创建 http请求
  3. 支持promise API
  4. 拦截请求和响应
  5. 转换请求和响应数据
  6. 取消请求
  7. 自动转换JSON数据
  8. 客户端支持方式XFRS攻击
// GET请求
axios.get('/user?ID=12345')
  .then(function (response) { 
    console.log(response)
  })
  .catch(function(error){
    console.log(error)
  })

axios.get('/user', {
    params: {
      ID:12345
    }
  })
  .then(function (response) { 
    console.log(response)
  })
  .catch(function(error){
    console.log(error)
  }) 


  // POST请求
axios.post('/user', {
  firstName: 'li',
  lastName:'xiaoming'
})
  .then(function (response) { 
    console.log(response)
  })
  .catch(function(error){
    console.log(error)
  }) 

  // 执行多个并发请求
function getUserAccount() {
    return axios.get('/user/12345')
}
function getUserPermissions() {
  return axios.get('/user/12345/permissions')
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    console.log("所有请求完成")
    console.log("请求结果1",acct)  
    console.log("请求结果2",perms)
  }))
上一篇 下一篇

猜你喜欢

热点阅读