Mr. Blue's breakfast

蓝sir的早餐


  • 首页

  • 归档

  • 标签

  • 分类

express使用CORS跨域资源共享设置中遇到的一些坑

发表于 2017-10-12

express支持跨域中间件

  • ajax请求必须配置 withCredentials的值为true,否则请求是不会带凭据的(cookie、HTTP认证及客户端SSL证明等)
  • 服务端接收带凭据的请求必须设置响应头属性 Access-Control-Allow-Credentials 为 true 否则浏览器不会把响应交给js(即responseText为空,status的值为0,而且会调用onerror()事件处理程序)
  • 当设置了 withCredentials的值为true 时服务端的 Access-Control-Allow-Origin 的属性不能为 * ,如有需要,需单独设置对应的响应头如req.headers.origin
  • IE10及更早版本都不支持 withCredentials 使用 XDomainRequest
1
2
3
4
5
6
7
8
9
10
11
12
13
setCORS() {
return (req, res, next) => {
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
// res.header("X-Powered-By", '3.2.1');
if (req.method === 'OPTIONS') {
return res.send('support CORS')
}
next();
}
},

其他参考 :XMLHttpRequest.withCredentials

react-redux 原理及基本实现

发表于 2017-06-15

react-redux 核心组件

Provider组件: 该组件接收一个store属性 将其内容挂载在context上 这样后代才可以都有办法拿到

高阶组件connect: 这个组件第一次执行传递两个’函数’分别是需要映射到props上的state和action(可以是对象,react-redux会自动调用redux中的bindActionCreators方法包装对象,把对象的每一个属性包装成dispatch方法并返回一个新对象);该组件执行返回的函数传入需要包装的组件,connect会把相应的state和dispatch当做属性传递给传入的组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import React from "react"
import PropTypes from "prop-types"
import {bindActionCreators} from 'redux'

class Provider extends React.Component{
static childContextTypes={
//设置上下的类型是对象
store:PropTypes.object
};
getChildContext(){
//获取并设置后代上下文的内容
return {store:this.props.store}
}
render(){
return this.props.children;
}
}
let connect =(mapStateToProps,mapDispatchToProps)=>(C)=>{
return class Proxy extends React.Component{
static contextTypes={
store:PropTypes.object
};
constructor(props,context){
super();
//将参数mapStateToProps 的解构赋值代理组件的状态
this.state=mapStateToProps(context.store.getState())
}
componentDidMount(){
this.unsubscribe = this.context.store.subscribe(()=>{
this.setState(mapStateToProps(this.context.store.getState()))
})
}
componentWillUnmount(){
this.unsubscribe()
}
render(){
let _disPatch;
if(typeof mapDispatchToProps === 'function'){
_disPatch = mapDispatchToProps(this.context.store.dispatch);
}else {
_disPatch = bindActionCreators(mapDispatchToProps,this.context.store.dispatch)
}

return <C {...this.state} {..._disPatch}/>
}
}
};
export {Provider,connect}

Redux 基本实现

发表于 2017-06-15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
function createStore(reducer) {
let state, listener = [], getState, dispatch, subscribe;
dispatch = action => {
state = reducer(state, action)
listener.forEach(item => item())
}
dispatch({})
subscribe = fn => {
listener = [...listener, fn]
return () => {
listener = listener.filter(item => item !== fn)
}
}
getState = () => JSON.parse(JSON.stringify(state))
return {dispatch, getState, subscribe}
}
/**
* combineReducers 合并reducers
* @param reducers[Object] 接收一个对象
* @returns {function()}
*/
function combineReducers(reducers) {

return (state = {}, action) => {
let obj = {}
for (let key in reducers) {
if(!reducers.hasOwnProperty(key)) continue;
obj[key] = reducers[key](state[key], action)
}
return obj
}
}

/**
* bindActionCreators 合并actions返回使用dispatch包装的结果
* @param actions
* @param dispatch
* @returns {{}}
*/
function bindActionCreators(actions,dispatch) {
//将actions 包装成 mapDispatchToProps返回的对象

let obj={};
for(let key in actions){
if(!actions.hasOwnProperty(key)) continue;
obj[key]=(...arg)=>{
dispatch(actions[key](...arg))
}
}
return obj;

}

React 编译渲染原理实现

发表于 2017-05-12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class React {
constructor() {
};


static createElement(type, options, ...arg) {
options = options || {};
// arg 储存的是剩下的参数集合,没有的话就是空数组

let obj = {type, key: null, ref: null, props: {}};

['key', 'ref'].forEach(item => {
if (item in options) {
obj[item] = options[item];
delete options[item]
}
});

obj.props = {...options};
let len = arg.length;
switch (len) {
case 0:
// 没有子节点,没有children
break;
case 1:
// 只有一个子节点,children 不是一个数组
obj.props.children = arg[0];
break;
default:
// 多个子节点
obj.props.children = JSON.parse(JSON.stringify(arg))
}

return obj
}
}

class ReactDOM {
static handChild(children, newEle) {
if (typeof children === 'object') {
// children 是一个虚拟dom
ReactDOM.render(children, newEle)
} else {
// children 是一个字符串
newEle.appendChild(document.createTextNode(children))
}
}

static render(objJSX, container, cb) {
let {type, props} = objJSX,
newEle = document.createElement(type);
for (let key in props) {
if (!props.hasOwnProperty(key)) continue;

if (key === 'children') {
let children = props['children'];
if (children instanceof Array) {
// children 是数组
children.forEach(itemChild => {
ReactDOM.handChild(itemChild, newEle)
});
continue
}
// 只有一个子节点
ReactDOM.handChild();
continue;
}

// class
if (key === 'className') {
newEle.setAttribute('class', props['className']);
continue;
}

// style 把props中的style的值依次遍历,并设置给元素
if (key === 'style') {
for (let key in props['style']) {
if (!props['style'].hasOwnProperty(key)) continue;
newEle.style[key] = props['style'][key]
}
}

newEle.setAttribute(key, props[key])
}
container.appendChild(newEle);
cb && cb()
}
}

React.createElement('div', undefined);
styleObj = {color: 'red'};
zeebin

zeebin

唯美食与爱不可辜负

4 日志
8 标签
GitHub
© 2015 — 2025 zeebin 京ICP备2023015256号-1
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.3