一、说明
原生js提供了两种数据请求方式fetch,ajax
- ajax需要封装的, fetch不需要
- ajax不太符合MV* 开发方式,fetch可以认为是js为了MV*方式做的量身打造
- fetch也是Promise
功能:用fetch请求动态数据
1、get请求
(1)不带参数
1 // 通过fetch获取百度的错误提示页面 2 fetch('https://www.baidu.com/search/error.html') // 返回一个Promise对象 3 .then((res)=>{ 4 return res.text() // res.text()是一个Promise对象 5 }) 6 .then((res)=>{ 7 console.log(res) // res是最终的结果 8 })
(2)带参数:
get请求参数是连接在url上
1 methods: { 2 get () { 3 fetch(`${ BASE_URL }/get.php?a=1&b=2`)//get请求参数是连接在url上 4 .then( data => data.text() ) 5 .then( res => { 6 this.num = res 7 }) 8 .catch( err => console.log( err )) 9 },
method: 'GET'不写默认是get请求
2、post请求
(1)不带参数
1 // 通过fetch获取百度的错误提示页面 2 fetch('https://www.baidu.com/search/error.html', { 3 method: 'POST' // 指定是POST请求 4 }) 5 .then((res)=>{ 6 return res.text() 7 }) 8 .then((res)=>{ 9 console.log(res) 10 })
(2)带参数
post请求传递参数:
body: new URLSearchParams([["a", 1],["b", 2]]).toString()
注意:POST请求的参数,一定不能放在URL中,这样做的目的是防止信息泄露。
1 post () { 2 /* 3 1. post请求参数如何携带 4 */ 5 fetch(`${ BASE_URL }/post.php`,{ 6 method: 'POST', 7 // body: JSON.stringify({ 8 // a: 1, 9 // b: 2 10 // }) 11 headers: new Headers({ 12 'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交 13 }), 14 body: new URLSearchParams([["a", 1],["b", 2]]).toString() 15 }).then( data => data.text() ) 16 .then( res => { 17 this.sum = res 18 }) 19 .catch( err => console.log( err )) 20 },
总结:
fetch( url, config ).then().then().catch()
1 getMovies () { 2 /* 第一个then是为数据格式化,可以格式化的数据类型有: json text blob[ 二进制 ] 3 第二个then才是得到的数据 4 */ 5 // fetch( url, config ).then().then().catch() 6 7 fetch('./mock/movie.json') 8 .then( data => data.json() ) 9 .then( res => { 10 console.log("兵哥: getMovies -> res", res) 11 this.movies = res.movieList 12 }) 13 }
得到json格式数据:
1 // 通过fetch获取百度的错误提示页面 2 fetch('https://www.baidu.com/rec?platform=wise&ms=1&rset=rcmd&word=123&qid=11327900426705455986&rq=123&from=844b&baiduid=A1D0B88941B30028C375C79CE5AC2E5E%3AFG%3D1&tn=&clientWidth=375&t=1506826017369&r=8255', { // 在URL中写上传递的参数 3 method: 'GET', 4 headers: new Headers({ 5 'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON 6 }) 7 }) 8 .then((res)=>{ 9 return res.json() // 返回一个Promise,可以解析成JSON 10 }) 11 .then((res)=>{ 12 console.log(res) // 获取JSON数据 13 })
格式化数据:
data.json()
data.text()
处理数据可以使用querystring
1 const qs = require( 'querystring' ) 2 const str = 'a=1&b=2' 3 const obj = { a: '1', b: '2' } 4 console.log( qs.parse( str )) 5 console.log( qs.stringify( obj ))
强制带Cookie:
1 // 通过fetch获取百度的错误提示页面 2 fetch('https://www.baidu.com/search/error.html', { 3 method: 'GET', 4 credentials: 'include' // 强制加入凭据头 5 }) 6 .then((res)=>{ 7 return res.text() 8 }) 9 .then((res)=>{ 10 console.log(res) 11 })
二、fetch的封装
1 /** 2 * 将对象转成 a=1&b=2的形式 3 * @param obj 对象 4 */ 5 function obj2String(obj, arr = [], idx = 0) { 6 for (let item in obj) { 7 arr[idx++] = [item, obj[item]] 8 } 9 return new URLSearchParams(arr).toString() 10 } 11 12 /** 13 * 真正的请求 14 * @param url 请求地址 15 * @param options 请求参数 16 * @param method 请求方式 17 */ 18 function commonFetcdh(url, options, method = 'GET') { 19 const searchStr = obj2String(options) 20 let initObj = {} 21 if (method === 'GET') { // 如果是GET请求,拼接url 22 url += '?' + searchStr 23 initObj = { 24 method: method, 25 credentials: 'include' 26 } 27 } else { 28 initObj = { 29 method: method, 30 credentials: 'include', 31 headers: new Headers({ 32 'Accept': 'application/json', 33 'Content-Type': 'application/x-www-form-urlencoded' 34 }), 35 body: searchStr 36 } 37 } 38 fetch(url, initObj).then((res) => { 39 return res.json() 40 }).then((res) => { 41 return res 42 }) 43 } 44 45 /** 46 * GET请求 47 * @param url 请求地址 48 * @param options 请求参数 49 */ 50 function GET(url, options) { 51 return commonFetcdh(url, options, 'GET') 52 } 53 54 /** 55 * POST请求 56 * @param url 请求地址 57 * @param options 请求参数 58 */ 59 function POST(url, options) { 60 return commonFetcdh(url, options, 'POST') 61 } 62 GET('https://www.baidu.com/search/error.html', {a:1,b:2}) 63 POST('https://www.baidu.com/search/error.html', {a:1,b:2})