文档服务地址:http://47.92.0.57:3000/ 周报索引地址:http://47.92.0.57:3000/s/NruNXRYmV

Commit 9fcdb500 by 安博

update readme.md

parent 079391c5
......@@ -865,3 +865,49 @@ let proxyOption ={target:proxyPath,changeOrigoin:true};
app.use("/api",proxyMiddleWare(proxyOption)) //对api请求使用代理
```
前端服务器代理的好处是对于用户而言只能看到前端服务器的地址,后端服务器的安全性得到提高;同时代理发生在内网环境,速度快。
第6章          跨页面数据存储与session
==========
6.1          跨页面数据存储
---------
所谓跨页面数据存储,即同一域名下的各个标签能够访问某个共享的数据。这样在设计某些功能的时候会带来不少方便。
通常的跨页面存储方式有:`localStorage` `sessionStorage` `cookie`
localStorage和sessionStorage比较类似,提供一组简单的API:
`getItem(key)`
`setItem(key,value)`
`clear()`
这三个API的意思都非常明显,需要注意的是item的value只支持字符串,如果需要存储JSON可以使用`JSON.stringfy()`。存储于其中的数据在同一个域名的标签之间共享。
如果需要实时监听数据改变,可以使用
```
addEventListener('storage', e=>{
console.log(e.oldValue);
console.log(e.newValue);
console.log(e.url);
console.log(e.storageArea);
console.log(e.key);
})
```
字段意义也都非常清楚。注意事件只会在未直接修改数据的页面触发。
localStorage的保存时间是永久,而sessionStorage的保存时间是浏览器关闭之前。
6.2          session
--------
首先请自行了解cookie和session之间的关系。
浏览器端可以使用`document.cookie`访问cookie。而cookie中有一个`httpOnly`的字段,用于限制浏览器脚本对cookie内容的访问,不过这并不影响浏览器向服务器发送cookie。好的做法是服务器设置该字段为`true`,然后向其中写入sessionID或者token之类的字段。服务器可以自己选择session数据的存放方式,比如内存或者持久化到数据库中,而不是将这些数据放到前端处理。
前端如果需要保留一个域名下的某些可公开数据,应当使用localStorage之类的方式,不可公开的数据全部交由服务器端session处理。即,完全不信任前端。
cookie可以设置过期方式与过期时间字段。
6.3          ant框架中的权限控制
------
......@@ -175,7 +175,7 @@ export const getRouterData = app => {
component: dynamicWrapper(app, [], () => import('../routes/play/play')),
},
'/play/p1/p2': {
component: dynamicWrapper(app, ['play'], () => import('../routes/play/play')),
component: dynamicWrapper(app, ['play','token'], () => import('../routes/play/play')),
},
// '/user/:id': {
// component: dynamicWrapper(app, [], () => import('../routes/User/SomeComponent')),
......
......@@ -2,7 +2,7 @@ import { play, testAPI } from '../services/api';
export default {
namespace: 'play',
state: {},
state: {data:{time:666}},
effects: {
*getTime(_, { call, put }) {
const response = yield call(play);
......
// import { xxx } from '../services/xxx';
export default {
namespace: "token",
state: {token:0},
effects: {
* fetch({payload}, {call, put})
{
yield put({type: 'save', newToken: payload});
},
},
reducers: {
save(state, {newToken})
{
return {
...state,
token:newToken
};
},
},
};
import React, { Component, Fragment } from 'react';
import { connect } from 'dva';
import React, {Component, Fragment} from 'react';
import {connect} from 'dva';
@connect(({ play, loading }) => ({
play,
@connect(({play, token, loading}) => ({
play, token,
loading: loading.effects['play/getTime'],
}))
export default class play extends Component {
componentDidMount() {
const { dispatch } = this.props;
dispatch({ type: 'play/getTime' });
componentDidMount()
{
const {dispatch} = this.props;
dispatch({type: 'play/getTime'});
typeof +localStorage.getItem('token') === "number" ? null : localStorage.setItem('token', 0);
dispatch({type: 'token/fetch', payload: localStorage.getItem('token')});
addEventListener('storage', e => {
const {dispatch} = this.props;
dispatch({type: 'token/fetch', payload: e.newValue});
});
}
render() {
const { play } = this.props;
refresh = e => {
e.preventDefault();
const {dispatch} = this.props;
dispatch({type: 'play/getTime', payload: {name: '12', email: '189.cn', cellPhone: '123'}});
let newToken = typeof +localStorage.getItem('token') === "number" ? +localStorage.getItem('token') + 1 : 0;
localStorage.setItem('token', newToken);
dispatch({type: 'token/fetch', payload: newToken});
};
render()
{
const {play} = this.props;
console.log(play);
const data = play.data || { time: 'error' };
const data = play.data || {time: 'error'};
console.log(data);
const time = data.time || 'error';
const testRep = JSON.stringify(play.testRep);
//let test = localStorage.getItem('token');
let test = this.props.token;
console.log(test);
return (
<div>
{testRep}
<button style={{ marginLeft: 10 }} onClick={this.refresh}>
{time}
<button style={{marginLeft: 10}} onClick={this.refresh}>
刷新时间
</button>
{test.token}
</div>
);
}
refresh = e => {
e.preventDefault();
const { dispatch } = this.props;
dispatch({ type: 'play/testAPI', payload: { name: '12', email: '189.cn', cellPhone: '123' } });
};
}
import fetch from 'dva/fetch';
import { notification } from 'antd';
import { routerRedux } from 'dva/router';
import {notification} from 'antd';
import {routerRedux} from 'dva/router';
import store from '../index';
const codeMessage = {
......@@ -23,11 +23,14 @@ const codeMessage = {
601: '自定义错误码601',
};
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
function checkStatus(response)
{
if (response.status >= 200 && response.status < 300)
{
return response;
}
if (response.status >= 600) {
if (response.status >= 600)
{
return response;
}
const errortext = codeMessage[response.status] || response.statusText;
......@@ -42,6 +45,20 @@ function checkStatus(response) {
}
/**
* 设置代理,用于支持跨域
* @param path
* @param proxyUrl
* @param port
* @returns {*}
*/
function setProxy(path, {proxyUrl, port})
{
if (proxyUrl && port)
return proxyUrl + ':' + port + path;
else return path;
}
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
......@@ -50,18 +67,24 @@ function checkStatus(response) {
*/
export default function request(url, options) {
const defaultOptions = {
credentials: 'include',
mode: 'cors',//手动开启跨域
credentials: 'include',//允许跨域cookie
//credentials: 'same-origin',//只允许同域cookie
};
const newOptions = { ...defaultOptions, ...options };
if (newOptions.method === 'POST' || newOptions.method === 'PUT') {
if (!(newOptions.body instanceof FormData)) {
const newOptions = {...defaultOptions, ...options};
if (newOptions.method === 'POST' || newOptions.method === 'PUT')
{
if (!(newOptions.body instanceof FormData))
{
newOptions.headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
...newOptions.headers,
};
newOptions.body = JSON.stringify(newOptions.body);
} else {
}
else
{
// newOptions.body is FormData
newOptions.headers = {
Accept: 'application/json;*/*',
......@@ -70,33 +93,41 @@ export default function request(url, options) {
}
}
//在这里对url做一次代理
url = setProxy(url, {proxyUrl: null, port: null});
return fetch(url, newOptions)
.then(checkStatus)
.then(response => {
if (newOptions.method === 'DELETE' || response.status === 204) {
if (newOptions.method === 'DELETE' || response.status === 204)
{
return response.text();
}
return response.json();
})
.catch(e => {
const { dispatch } = store;
const {dispatch} = store;
const status = e.name;
if (status === 401) {
if (status === 401)
{
dispatch({
type: 'login/logout',
});
return;
}
if (status === 403) {
if (status === 403)
{
dispatch(routerRedux.push('/exception/403'));
return;
}
if (status <= 504 && status >= 500) {
if (status <= 504 && status >= 500)
{
dispatch(routerRedux.push('/exception/500'));
return;
}
if (status >= 404 && status < 422) {
if (status >= 404 && status < 422)
{
dispatch(routerRedux.push('/exception/404'));
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment