仿豆瓣APP项目之一:前后端交互

一、前后端的交互
1.登录
使用mock.js模拟登录数据以及登录时的请求网址,使用axios模拟登录请求过程。
关于mock.js
首先在项目的main.js根文件中引入自己写的mock文件夹
import '@/mock/index.js' // 该项目所有请求使用mockjs模拟

再在mock的index主文件中运入mockjs

import Mock from 'mockjs'
import loginAPI from './login.js'

//登录相关
Mock. mock( / \/ login \/ loginbyemail/, 'post', loginAPI.loginByEmail);

Mock.mock( rurl, rtype, function( options ) )

记录用于生成响应数据的函数。当拦截到匹配 rurl 和 rtype 的 Ajax 请求时,函数 function(options) 将被执行,并把执行结果作为响应数据返回。

/login/loginbyemail是模拟的拦截请求的网址(参数rurl)

post是请求类型(参数rtype)

loginAPI.loginByEmail是拦截到请求后回请的函数(参数function(options) )

通用的mock模拟请求的模板是:

Mock.mock( rurl?, rtype?, template|function( options ) )

rurl

可选。

表示需要拦截的 URL,可以是 URL 字符串或 URL 正则。例如 /\/domain\/list\.json/'/domian/list.json'

rtype

可选。

表示需要拦截的 Ajax 请求类型。例如 GETPOSTPUTDELETE 等。

template

可选。

表示数据模板,可以是对象或字符串。例如 { 'data|1-10':[{}] }'@EMAIL'

function(options)

可选。

表示用于生成响应数据的函数。

options

指向本次请求的 Ajax 选项集,含有 urltype  body 三个属性,参见 XMLHttpRequest 规范

在项目中我自设了可登录成功的两个数据:
const userList = [
{
email: '[email protected]',
password: '123456'
},
{
email: '[email protected]',
password: '123456'
}
]
在很多情况下可以利用mock随机模拟数据:

Mock.Random

Mock.Random 是一个工具类,用于生成各种随机数据。

Mock.Random 的方法在数据模板中称为『占位符』,书写格式为 @占位符(参数 [, 参数]) 。

var Random = Mock.Random
Random.email()
// => "[email protected]"
Mock.mock('@email')
// => "[email protected]"
Mock.mock( { email: '@email' } )
// => { email: "[email protected]" }

以上两个是mock常用到的两个功能。
关于axios:
本项目使用axios这个ajax库处理拦截请求
要使axios对所有组件可全局使用,需要在main.js中运入axios
import axios from 'axios'
同时要将axios应用到vue的原型上
Vue.prototype.$axios = axios
代码:
export default {
//这是在模拟处理axios发送post请求后,后台的处理
loginByEmail: config => {
//获取用户输入的用户名和密码
const {email,password} = JSON. parse(config.body)
let loginSuccess = false
for( let i = 0;i <userList.length;i ++) {
if(userList[i].email ==email && userList[i].password ==password){
loginSuccess = true;
break;
}
}
console. log(loginSuccess);
if(loginSuccess){
//登录成功
return {
login: 'success'
}
} else{
return {
login: 'error'
}
}
}
}

axios API

可以通过向 axios 传递相关配置来创建请求

axios(config)
// 发送 POST 请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
axios(url[, config])
// 发送 GET 请求(默认的方法)
axios('/user/12345');
config代表传递的相关配置

上面红色方框中的部分就代表登录请求的config

响应结构

某个请求的响应包含以下信息


利用 .then(callback(response)).catch(callback(err))进行响应处理

拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

如果你想在稍后移除拦截器,可以这样:

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

可以为自定义 axios 实例添加拦截器

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

2.向豆瓣提供的API发送请求

起初是想利用axios完成所有的请求,由于axios对于跨域请求的局限性,这里利用superagent来完成

跨域请求:

由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。具体可以查看下表(来源


JSONP

这种方式主要是通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。

实际项目中JSONP通常用来获取json格式数据,这时前后端通常约定一个参数callback,该参数的值,就是处理返回数据的函数名称。

缺点:

  1、这种方式无法发送post请求(这里

  2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

Proxy代理

这种方式首先将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。

需要注意的是如果你代理的是https协议的请求,那么你的proxy首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。

对于同一请求浏览器通常会从缓存中读取数据,我们有时候不想从缓存中读取,所以会加一个preventCache参数,这个时候请求url变成:url?preventCache=12345567....;这本身没有什么问题,问题出在当使用某些前端框架(比如jquery)发送proxy代理请求时,请求url为proxy?url,同时设置preventCache:true,框架不能正确处理这个参数,结果发出去的请求变成proxy?url&preventCache=123456(正长应为proxy?url?preventCache=12356);后端截取后发送的请求为url&preventCache=123456,根本没有这个地址,所以你得不到正确结果。

CORS

这是现代浏览器支持跨域资源请求的一种方式。

当你使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。

XDR

这是IE8、IE9提供的一种跨域解决方案,功能较弱只支持get跟post请求,而且对于协议不同的跨域是无能为力的,比如在http协议下发送https请求。

axios这个ajax库默认只支持CORS这种跨域方式的请求,本地localhost像豆瓣API发送请求需要用到jsonp,故用superagent这个ajax库

superagent:

使用superagent时需要向当前js文件引入,若是利用jsonp实现跨域,还需要额外引入jsonp

import request from 'superagent'
import jsonp from 'superagent-jsonp'

请求基础

一个请求的初始化可以用请求对象里合适的方法来执行,然后调用end()来发送请求,下面是一个简单的get请求


 
 request
   .get('/search')
   .end(function(res){
   });

请求方法也可以通过参数传递:

 
request('GET', '/search').end(callback);

node客户端也允许提供绝对路径:

 
 request
   .get('http://example.com/search')
   .end(function(res){
   });

delete,head,post,put和别的http动作都可以使用,来换个方法看看:

 
request
  .head('/favicon.ico')
  .end(function(res){
  });

delete是一个特列,因为它是系统保留的关键字,所以应该用.del()这个名字:

 
request
  .del('/user/1')
  .end(function(res){
  });

http请求默认的方法为get,所以就像你看到的,下面的这个例子也是可用的:

 
request('/search', function(res){
 });

解析响应内容

superagent会解析一些常用的格式给请求者,当前支持application/x-www-form-urlencoded,application/json,multipart/form-data.

JSON/Urlencoded

res.body是解析后的内容对象,比如一个请求响应'{"user":{"name":"tobi"}}'字符串,res.body.user.name将会返回tobi,同样的,x-www-form-urlencoded格式的user[name]=tobi解析完的值,也是一样的.

res.text 包含未解析前的响应内容

res.header包含解析之后的响应头数据,键值都是node处理成小写字母形式,比如res.header['content-length'].

 res.status响应状态标识可以用来判断请求是否成功

 可以通过 req.abort() 来中止请求.
 可以通过req.timeout()来定义超时时间,然后当超时错误发生时,为了区别于别的错误,err.timeout属性被定义为超时时间,注意,当超时错误发生后,后续的请求都会被重定向.不是每个请求.

综上所示:axios和superagent各有优点,根据具体情况进行选择即可。

猜你喜欢

转载自blog.csdn.net/qq_35585701/article/details/79382074