AlexZ33 / lessions

自己练习的各种demo和课程
12 stars 2 forks source link

前后端分离 #24

Open AlexZ33 opened 5 years ago

AlexZ33 commented 5 years ago

前后端分离项目,一般前后端公用域名,只有后端API接口需要登录认证,且一般是需要通过ajax发送请求,ajax有两个特点

const server = new WebpackDevServer(compiler, { ... proxy: { '/api': 'http://127.0.0.1:12347/' // 后端API接口的prefix和端口 } })


- 不能正常接收302重定向,后端API接口认证不通过的时候需要返回401及相关desc信息

// 登录认证失败,HTTP返回内容
CODE 401
BODY
{
  "desc":"htts://xxxxx.com"
}

// src/utils/axios.js

// 请求返回全局拦截 axios.interceptors.response.use( response => { ... }, err => { if (err && err.response) { switch (err.response.status) { ... case 401: err.message = '未授权,请重新登录(401)' // service=后端登录接口 window.location.href = err.response.data.desc + '/login?service=' + encodeURIComponent(window.location.origin + '/dashboard/login?follow=' + encodeURIComponent(window.location.href)) break ... } notify(err.message, 'error') } ... } )


- 手动页面跳转

// window.location.href = 目标url window.localtion.href = '/'

// 通过history API this.props.history.push('/')

- URL风格(spa项目)
开发过程中,我们整个项目只有一个html入口,所以整个项目本质上是个单页应用,但是用从URL上看是多页的,URL风格有两种(history / hash)

// 默认url模式,使用browserHistory管理页面栈history http://localhost/pages http://localhost/pages/1/comments

// 默认模式在正式上线后,需要额外的nginx路由配置,将所有前端url执向index.html,例如 location / { try_files $uri /index.html; }

// hash,锚连接,使用hashHistory管理页面history http://localhost/#/pages http://localhost/#/pages/1/comments

AlexZ33 commented 5 years ago

跨域

dataType、contentType、withCredential

dataType

  dataType有些人可能会觉得陌生,但说起jquery或者是zepto的ajax请求,就想起来了,使用$.ajax请求时,经常会带上参数dataType : 'json',如下图:

   image

  dataType属性是为了表明用什么格式解析服务端响应的数据,json表示ajax接收服务端响应的数据时解析为JSON格式,但是你会发现有时候即使不设置dataType,也能够正常解析响应数据,页面上该显示的内容依然可以正常显示,因为框架贴心,zepto在你不设置dataType的时候,默认读取服务端的响应头Content-Type,例如zepto把服务端的响应头ContentType : application/json转换成dataType : 'json',所以只要跟服务端约定好了,前端开发中可以不需要设置dataType,当然了,设置这个属性会更让代码更健壮。

  所以,dataType只是框架(zepto/jquery等)封装时为了方便解析而定义的属性,并非是原生ajax的属性。

AlexZ33 commented 5 years ago

contentType

  严格来讲是Content-Type,这是http头里面的一个属性,无论是请求头还是响应头都可以有这个属性,但作用并不一样,另外,zepto的ajax请求配置中可以设置contentType,如下图,它是用来设置请求头中的Content-Type; image 先说请求头中的Content-Type,是为了告诉服务端该请求实例的数据格式,一般情况下不需要设置,除非服务端有特殊要求,但如果设置的值超过这三个值application/x-www-form-urlencoded、multipart/form-data、text/plain,CORS跨域请求时会触发预请求,至于什么是预请求,这里不赘述,可以自行查一下百科;

  再看看返回头中的Content-Type,反过来,是服务端告诉客户端响应实例的数据格式,浏览器也会跟据格式来决定是显示成网页、JS、CSS或是下载等等,对于浏览器来讲,这是必需的属性。

AlexZ33 commented 5 years ago

withCredentials

默认情况下,一般浏览器的CORS跨域请求都是不会发送cookie等认证信息到服务端的,除非指定了xhr.withCredentials = true,但是只有客户端单方面的设置了这个值还不行,服务端也需要同意才可以,所以服务端也需要设置好返回头Access-Control-Allow-Credentials: true;还有一点要注意的,返回头Access-Control-Allow-Origin的值不能为星号,必须是指定的域,否则cookie等认证信息也是发送不了。

关于withCredentials,还可以参阅mdn的XMLHttpRequest.withCredentials 这里:

image

AlexZ33 commented 5 years ago

如常见问题:

跨域带cookie 5条cookie 只传过去了2条,会是什么原因?

考虑🤔