第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]

本站PHP后端接口:  http://code.liuxinxiu.com/php/Interface/Jsoncallback.php?GUID=1&&Jsoncallback=1

本实例用 ES5 + JSX 语法编写[对应实例] : http://liuxinxiu.com/React_Ajax_setState_Render_UI_ES5/

JavaScript代码
  1. /****** ES6输入文件[调用模块依赖] ******/  
  2. import React, { Component, PropTypes } from 'react'  
  3. import $ from 'n-zepto'  
  4.   
  5. /****** ES5输入文件[调用模块依赖] ******/  
  6. //var React=require('react');  
  7. //var $=require('n-zepto');  
  8.   
  9. //import * as from './commentList.js'  
  10. //import list from './commentList.js';  
  11.   
  12.   
  13. /****** 本地模拟Array数据******/  
  14. var movies = [  
  15.     {  
  16.         id: 1,  
  17.         name: '速度与激情001',  
  18.         date: 2011  
  19.     },  
  20.     {  
  21.         id: 2,  
  22.         name: '速度与激情002',  
  23.         date: 2009  
  24.     }  
  25. ];  
  26.   
  27. /****** 外部子组件map数组当做模板之用 ES5 + JSX 语法编写 ******/  
  28. var MoviesList = React.createClass({  
  29.     render: function () {  
  30.         // this.props 用于从组件外部传入数据  
  31.         var _movies = this.props._movies;  
  32.         return (  
  33.             <li className="datali">  
  34.         {_movies.id}-{_movies.name}  
  35.             </li>  
  36.         )  
  37.     }  
  38. });  
  39.   
  40. /****** 外部子组件map数组当做模板之用 ES6 + JSX 语法编写 ******/  
  41. let CommentList=class CommentList extends Component {  
  42.     constructor(props) {  
  43.         super(props);  //ES6调用父类构造函数super不能少!  
  44.         this.state = {  
  45.              wording: '你好呀, '  
  46.         };  
  47.     }  
  48.   
  49.     /****** Ajax子组件中[主体模板] ******/  
  50.     render(){  
  51.         return <ul>{this.props.comments.map(this.renderComment)}</ul>;  
  52.     }  
  53.   
  54.     /****** Ajax子组件中[嵌套模板] ******/  
  55.     renderComment({plat,type,name,guid,cre_time,lottery}){  
  56.         return (  
  57.             <li>{plat}--{type}--{name}--{guid}--{cre_time}--{lottery}</li>  
  58.         )  
  59.     }  
  60.   
  61. }  
  62.   
  63. /****** 使用ES6 + JSX 语法编写 class xx extends React.Component{} 创建一个组件 ******/  
  64. class CommentListContainer extends Component {  
  65.     /****** [ES6-constructor||ES5-getInitialState] ******/  
  66.     constructor(){  
  67.         super();  
  68.         this.state = {  
  69.             loading: true,  
  70.             title: '我喜欢的电影',  
  71.             movies: [],  
  72.         comments: []  
  73.     }  
  74.     }  
  75.   
  76.     componentDidMount(){  
  77.         $.ajax({  
  78.               type: 'GET',  
  79.               url: 'http://code.liuxinxiu.com/php/Interface/Jsoncallback.php',  
  80.               data: {GUID:'1'},  
  81.               dataType:'jsonp', //告诉Ajax调用$jsonp  
  82.               jsonp: "Jsoncallback", //zpeto-1.2支持自定义回调名  
  83.               success: function(data){  
  84.                   var yy=JSON.stringify(data);  
  85.                   var tlist=JSON.stringify(data.enttityList);  
  86.                   //console.log(tlist);  
  87.                   //console.log(this.state.title+'22');  
  88.                   this.setState({  
  89.                         comments:data.enttityList,  
  90.                         lottery:data.enttityList[0].lottery  
  91.                   });  
  92.                   var commentsStr=JSON.stringify(this.state.comments);  
  93.                   console.log("\n--->>commentsStr:\n"+commentsStr); //查看获取的数据  
  94.                   //console.log(this.state.comments+'33')  
  95.               }.bind(this),  
  96.               error: function(xhr, type){  
  97.                   alert(xhr+type+'Ajax error!');  
  98.               }  
  99.         });  
  100.         //console.log(this.state.comments+'++++--!!'); //ajax底下拿不到结果因为提前于异步  
  101.     }  
  102.   
  103.     render(){  
  104.         return <CommentList comments={this.state.comments}/>;  
  105.     }  
  106. }  
  107.   
  108.   
  109. /****** ES5输出给router ******/  
  110. //module.exports=DemoComponent;  
  111.   
  112. /****** ES6输出给router ******/  
  113. export default CommentListContainer;  
Tags: , , , , ,

本站PHP后端接口:  http://code.liuxinxiu.com/php/Interface/Jsoncallback.php?GUID=1&&Jsoncallback=1

 本实例用 ES6 + JSX 语法编写[对应实例] : http://liuxinxiu.com/React_Ajax_setState_Render_UI_ES6/

JavaScript代码
  1. //import React, { Component, PropTypes } from 'react'  
  2. //import $ from 'n-zepto'  
  3. var React=require('react'); //Es-5
  4. var $=require('n-zepto');   //Es-5
  5.   
  6. //import * as from './commentList.js'  
  7. //import list from './commentList.js';  
  8.   
  9.   
  10. /****** 外部子组件map数组当做模板之用 ******/  
  11. var MoviesList = React.createClass({  
  12.     render: function () {  
  13.         // this.props 用于从组件外部传入数据  
  14.         ar _movies = this.props._movies;  
  15.         return (  
  16.             <li className="datali">
  17.                 {_movies.id}-{_movies.name}
  18.             </li>  
  19.         )  
  20.     }
  21. });  
  22.   
  23. /****** 本地模拟Array数据******/  
  24. var movies = [  
  25.     {  
  26.         id: 1,  
  27.         name: '速度与激情001',  
  28.         date: 2011  
  29.     },  
  30.     {  
  31.         id: 2,  
  32.         name: '速度与激情002',  
  33.         date: 2009  
  34.     }  
  35. ];  
  36.   
  37.   
  38. /****** 使用Es5语法 React.createClass 创建一个组件 ******/  
  39. var DemoComponent = React.createClass({  
  40.     /****** 使用 getInitialState 的返回值作为数据的默认值 ******/  
  41.     getInitialState: function () {  
  42.     // this.state 用于存储数据comments被Ajax赋值要先定义个名称  
  43.         return {  
  44.             loading: true,  
  45.             title: '我喜欢的电影',  
  46.             movies: [],  
  47.         comments: []  
  48.         }  
  49.     },  
  50.   
  51.     componentDidMount: function() {  
  52.     $.ajax({  
  53.         type: 'GET',  
  54.         url: 'http://code.liuxinxiu.com/php/Interface/Jsoncallback.php',  
  55.         data: {GUID:'1'},  
  56.         dataType:'jsonp', //告诉Ajax调用$jsonp  
  57.         jsonp: "Jsoncallback", //zpeto-1.2支持自定义回调名  
  58.         success: function(data){  
  59.             var yy=JSON.stringify(data);  
  60.             var tlist=JSON.stringify(data.enttityList);  
  61.             console.log(tlist);  
  62.             //console.log(this.state.title+'22')  
  63.             this.setState({  
  64.                 comments:data.enttityList,  
  65.                 lottery:data.enttityList[0].lottery  
  66.             });  
  67.             var slist=JSON.stringify(this.state.comments);  
  68.             console.log(slist)  
  69.             //console.log(this.state.comments+'33')  
  70.         }.bind(this),  
  71.         error: function(xhr, type){  
  72.             alert(xhr+type+'Ajax error!'); //error
  73.         }  
  74.     });  
  75.     //console.log(this.state.comments+'++++--!!'); //ajax底下拿不到结果因为提前于异步  
  76.     },  
  77.   
  78.     render: function () {  
  79.         // this.state 用于存储当前的数据  
  80.         var comments = this.state.comments;  
  81.   
  82.         //var dataHtml=movies.map(<p>{name}</p>);// 注意这里 bind(this) 修正了上下文  
  83.   
  84.     /****** Movies子模板 ******/  
  85.         function renderMovies({id,name}){  
  86.             return <li>{id}-{name}</li>;  
  87.         }  
  88.     /****** Movies大模板[内嵌子模板] ******/  
  89.         //var dataHtml = movies.map(renderMovies);  
  90.   
  91.     /****** Movies大模板[外调子模板] ******/  
  92.         var dataHtml = movies.map(function(movies){  
  93.             return (  
  94.                 <MoviesList _movies={movies}/>  
  95.             )  
  96.     }.bind(this));// 注意这里 bind(this) 修正了上下文  
  97.     //console.log('movies:'+movies+'--'+'dataHtml:'+dataHtml);  
  98.   
  99.   
  100.     /****** Ajax子模板******/  
  101.         function renderComment({plat,type,name,guid,cre_time,lottery}){  
  102.             return <li>{plat}--{type}--{name}--{guid}--{cre_time}--{lottery}</li>;  
  103.         }  
  104.     /****** Ajax大模板 ******/  
  105.         var AjaxHtml = this.state.comments.map(renderComment);  
  106.     //var AjaxHtml='11'  
  107.     console.log('comments:'+comments+'--'+'AjaxHtml:'+AjaxHtml);  
  108.   
  109.     return (  
  110.         <ul>{AjaxHtml}</ul>  
  111.     )  
  112.     }  
  113. });  
  114.   
  115. /****** ES5输出给router ******/  
  116. module.exports=DemoComponent;  
  117.   
  118. /****** ES6输出给router ******/  
  119. //export default DemoComponent;  

 

Tags: , , ,

React 速记

[不指定 2016/09/23 21:06 | by 刘新修 ]

使用ES5||ES6 -- 输入文件示例 [调用所依赖的模块]:

JavaScript代码
  1. /****** ES5调用依赖模块[require]被打包会自动生成关联代码 ******/  
  2. var MyComponent = require('./components/movie-list');  
  3.   
  4. /****** ES6调用依赖模块 ******/  
  5. import MyComponent from './components/movie-list';  

使用ES5||ES6 -- 输出文件示例[输出给被依赖模块]:

JavaScript代码
  1. /****** ES5输出给router ******/
  2. module.exports=DemoComponent;
  3.  
  4. /****** ES6输出给router ******/  
  5. //export default DemoComponent;  
  6.  

使用ES5 -- 创建一个组件:

JavaScript代码
  1. /****** 使用Es5语法 React.createClass 创建一个组件 ******/  
  2. var DemoComponent = React.createClass({  
  3.     /****** 使用 getInitialState 的返回值作为数据的默认值(!return) ******/  
  4.     getInitialState: function () {  
  5.         return {  
  6.             loading: true,  
  7.             title: '我喜欢的电影',  
  8.             // 注意这里将 外部传入的数据赋值给了 this.state  
  9.             movies: []  
  10.         }  
  11.     },  
  12.     /****** 输出HTML模板,此处可以调用子组件******/  
  13.     render: function () {  
  14.         return (  
  15.             <div className="component-hello">  
  16.         {this.state.title}  
  17.             </div>  
  18.         )  
  19.     }  
  20. });  

使用ES5 -- map遍历当前Array并调用渲染数据的[外部]子组件:

JavaScript代码
  1. /****** 使用Es5语法 遍历数组并调用外部子组件 ******/  
  2. var MoviesList=React.createClass({...});  
  3. var dataHtml = movies.map(function(movies){  
  4.    return (  
  5.         <MoviesList _movies={movies}/>  
  6.    )  
  7. }.bind(this));// 注意这里 bind(this) 修正了上下文  
  8. return (  
  9.    <ul>{dataHtml}</ul>  
  10. )  
  11.   
  12.   
  13. /****** 外部子组件map数组当做模板之用 ******/  
  14. var MoviesList = React.createClass({  
  15.     render: function () {  
  16.         // this.props 用于从组件外部传入数据  
  17.         var _movies = this.props._movies;  
  18.         return (  
  19.             <li className="datali">  
  20.         {_movies.id}-{_movies.name}  
  21.             </li>  
  22.         )  
  23.     }  
  24. });  

使用ES5 -- map遍历当前Array并调用渲染数据的[内部]子组件:

JavaScript代码
  1. /****** 使用Es5语法 遍历数组并调用内部子组件 ******/  
  2. function renderMovies({id,name}){  
  3.    return <li>{id}-{name}</li>;  
  4. }  
  5. var dataHtml = movies.map(renderMovies);  
  6. return (  
  7.    <ul>{dataHtml}</ul>  
  8. )  

Ajax获取接口数据并设置到state :

JavaScript代码
  1. componentDidMount(){  
  2.     $.ajax({  
  3.           type: 'GET',  
  4.           url: 'http://code.liuxinxiu.com/php/Interface/Jsoncallback.php', //JSONP接口
  5.           data: {GUID:'1'},  
  6.           dataType:'jsonp', //告诉Ajax调用$jsonp  
  7.           jsonp: "Jsoncallback", //zpeto-1.2支持自定义回调名  
  8.           success: function(data){  
  9.               var yy=JSON.stringify(data);  
  10.               var tlist=JSON.stringify(data.enttityList);  
  11.               //console.log(tlist);  
  12.               //console.log(this.state.title+'22');  
  13.               this.setState({  
  14.                     comments:data.enttityList,  
  15.                     lottery:data.enttityList[0].lottery  
  16.               });  
  17.               var commentsStr=JSON.stringify(this.state.comments);  
  18.               console.log("\n--->>commentsStr:\n"+commentsStr); //查看获取的数据  
  19.               //console.log(this.state.comments+'33')  
  20.           }.bind(this),  
  21.           error: function(xhr, type){  
  22.               alert(xhr+type+'Ajax error!');  
  23.           }  
  24.     });  
  25.     //console.log(this.state.comments+'++++--!!'); //ajax底下拿不到结果因为提前于异步  
  26. }  

react 的事件调用分类

C#代码
  1. 触摸事件:onTouchCancel\onTouchEnd\onTouchMove\onTouchStart  
  2. (只会在移动设备上接受)  
  3.    
  4. 键盘事件:onKeyDown\onKeyPress\onKeyUp  
  5.    
  6. 剪切事件:onCopy\onCut\onPaste  
  7.    
  8. 表单事件:onChange\onInput\onSubmit  
  9.    
  10. 焦点事件:onFocus\onBlur  
  11.    
  12. UI元素:onScroll(移动设备是手指滚动和PC的鼠标滑动)  
  13.    
  14. 滚动事件:onWheel(鼠标滚轮)  
  15.    
  16. 鼠标类型:onClick\onContextMenu(右键)\onDoubleClick\onMouseDown\onMouseEnter\  
  17.      onMouseLeave\onMouseMove\onMouseOut\onMouseOver\onMouseUp  
  18.   onDrag\onDrop\onDragEnd\onDragEnter\onDragExit\onDragLeave\onDragOver\onDragStart  

 

react 嵌套路由相关

[不指定 2016/09/21 12:58 | by 刘新修 ]

 /src/js/app.js

JavaScript代码
  1. import React, { PropTypes, Component } from 'react';  
  2. import {render} from 'react-dom';   //render((_component),Dom);  
  3. //import ReactDOM from 'react-dom';     //ReactDOM.render((_component),Dom);  
  4. import getRouter from './getRouter';  
  5. import { Router, Route, Link, IndexRoute, hashHistory } from 'react-router';  
  6.   
  7. /* using an ES6 transpiler, like babel */  
  8. //import { createHistory } from 'history/createBrowserHistory'  
  9. //import createBrowserHistory from 'history/createBrowserHistory';  
  10.   
  11. /* Import Component */  
  12. import Hello from '../components/hello/hello.jsx'  
  13. import Other from '../components/other/other.jsx'  
  14.   
  15. /* ensure test */  
  16. require.ensure(['./test'],function(require){  
  17.     var aModule = require('./test');  
  18.     console.log("xxxx");  
  19. },'test');  
  20.   
  21. /* create history for router */  
  22. //const history = createHistory()  
  23.   
  24. /* Router Config */  
  25. render((  
  26.   <Router history={hashHistory}>  
  27.     <Route path="/" component={getRouter}>  
  28.       <IndexRoute component={Hello} />  
  29.       <Route path="other" component={Other} />  
  30.     </Route>  
  31.   </Router>  
  32. ), document.getElementById('app'));  

/src/js/getRouter.js

JavaScript代码
  1. import React, { PropTypes, Component } from 'react';  
  2. export default React.createClass ({   
  3.   render() {  
  4.     return <div>  
  5.       {this.props.children}  
  6.     </div>  
  7.   }  
  8. });  

/src/components/hello/hello.jsx

JavaScript代码
  1. import React, { PropTypes, Component } from 'react';  
  2.   
  3. /* 导入组件样式hello.css */  
  4. import styles from './css/hello.css';  
  5.   
  6. //require("./css/hello.css");  
  7.   
  8. class Hello extends React.Component {   
  9.     render(){   
  10.         return (  
  11.         <div className="hello">  
  12.         <p>Hello World!!!!!!!...</p>  
  13.         <p>cll不错!</p>  
  14.         </div>  
  15.         );   
  16.     };  
  17. };  
  18. export default Hello;  

/src/components/other/other.jsx

JavaScript代码
  1. class Other extends React.Component {  
  2.   render() {  
  3.         return (  
  4.         <div>  
  5.         <p>this is other component!!!</p>  
  6.         <p>111111111cll不错!</p>  
  7.         </div>  
  8.         )  
  9.   }  
  10. }  
  11.   
  12. export default Other;  

支持来自任何域名的Post请求,验证请求参数必须有: [name、gender] 否则直接JSON返回错误!

JavaScript代码
  1. var http=require('http');  
  2. function server(){  
  3.     this.exec=function(route,req,res){  
  4.     var _self=this;  
  5.     /********** 获取客户端数组中的部分数据可向后多取 **********/  
  6.     this.arrv=function(o,n,p){  
  7.        var i,y,d,p;y=false;d='';  
  8.        for(i in o){  
  9.          if(o[i]==n&&p==undefined){i++;return o[i]};  
  10.          if(o[i]==n&&p!=undefined&&!isNaN(p)||y){  
  11.              var s;s=i;  
  12.              p=Number(p);  
  13.              if(p>0){  
  14.                 p--;s++;d+=o[s];y=true;  
  15.              }  
  16.              else{  
  17.                 return d;  
  18.              }  
  19.          }  
  20.        }  
  21.     };  
  22.     /********** 请求后端时可获取单个header头内地信息 **********/  
  23.     this.getReqHeaders=function(n){  
  24.         if(typeof(n)=='undefined'){  
  25.           console.log('getReqHeaders(n)变量没有定义!');  
  26.         }else{  
  27.             return _self.arrv(req.rawHeaders,String(n));  
  28.         }  
  29.     };  
  30.     /******** 获取客户端请求的header整体头部信息 ********/  
  31.     this.rawHeaders=function(state){  
  32.         var json={};  
  33.         if(!state){  
  34.             for(var i=0;i<req.rawHeaders.length;i++){  
  35.                 var s,s=i;  
  36.                 if(i%2==0){  
  37.                     s++;json[req.rawHeaders[i]]=req.rawHeaders[s];  
  38.                 }  
  39.             }  
  40.         }  
  41.         if(state){  
  42.             for(var i=0;i<req.rawHeaders.length;i++){  
  43.                 json[i]=req.rawHeaders[i];  
  44.             }  
  45.         }  
  46.         var jsonStr=JSON.stringify(json);//结果:"{'1':'a','2':'b','3':'c'}"  
  47.         var jsonObj=JSON.parse(jsonStr); //结果:[object Object]  
  48.         return jsonObj;  
  49.     };  
  50.   
  51.   
  52.     //接收参数 ------ sreq.on("data",function(data){});接收html中ajax传递的参数  
  53.     req.on("data",function(data){  
  54.   
  55.         /********* 打印提示||接受数据并反向代理到后端 *********/  
  56.         console.log("\n--->>\nReq.on('data')",req.method.toUpperCase()+" Use Proxy!");  
  57.   
  58.         /********* 使用代理||这里Post请求体是回调data *********/  
  59.         send(route,req,res,data);  
  60.     });  
  61.   
  62.     /********** 判断是GET请求类型||也可以代理给后端处理 **********/  
  63.     if(req.method.toUpperCase()=="GET"){  
  64.   
  65.         var params=[];  
  66.         //params=url.parse(request.url,true).query;  
  67.         //params['fruit']=compute(params);  
  68.         res.writeHeader(200,{  
  69.             "Content-type":"text/html; charset=utf-8"  
  70.         });  
  71.         res.write('<h1>It is forbidden for the URL request!</h1>');  
  72.         res.write('<hr><address>NodeJs/'+process.version);  
  73.         res.write(' at '+req.headers.host.split(':')[0]);  
  74.         res.write(' Port '+req.headers.host.split(':')[1]+'</address>');  
  75.         res.end();  
  76.   
  77.     }  
  78.     /********* 如有req.on("data",function(data){});就跳过了以下方法 ******/  
  79.     /********* 判断是POST请求类型||提交不走代理此方法是本机处理回调 **********/  
  80.     else if(req.method.toUpperCase()=='POSTo'){  
  81.   
  82.         var postData="";  
  83.         /********** 读取Post提交的数据 **********/  
  84.         req.addListener("data",function(data){  
  85.             postData+=data;  
  86.         });  
  87.   
  88.         /********** 数据读取完毕就会执行的监听 *********/  
  89.         req.addListener("end",function(){  
  90.            /********* 定义Post请求主体 *********/  
  91.            var query=require('querystring').parse(postData);  
  92.   
  93.            /************** 判断如果有POST过来数据 *************/  
  94.            if(query.name&&query.gender){  
  95.               console.log('Start a request...');  
  96.   
  97.                 var origin=_self.arrv(req.rawHeaders,'Origin');  
  98.                 console.log("origin:"+typeof req.rawHeaders+'---')  
  99.   
  100.   
  101.               /********** 代理转发至php,跨域全放开让后端去匹配验证 **********/  
  102.               //res.setHeader('Access-Control-Allow-Origin','*');  
  103.               //res.setHeader('Access-Control-Allow-Headers','X-Requested-With');  
  104.               //res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,OPTIONS');  
  105.               //send(route,req,res,query);  
  106.            }  
  107.            /****** 判断结束 ******/  
  108.         });  
  109.   
  110.     }  
  111.   
  112.   
  113.     /******** 请求后端接口 ********/  
  114.     function send(route,req,res,data){  
  115.   
  116.         /***************************************
  117.         var data={
  118.               name:'liuxinxiu',
  119.               gender:"male",
  120.               time:new Date().getTime()
  121.         };
  122.         ****************************************/  
  123.         //data=require('querystring').stringify(data);  
  124.         var rawHeaders=_self.rawHeaders();  
  125.   
  126.         /********** 判断一个对象是哪中类型的对象 **********/  
  127.         function isArray(obj){  
  128.               return Object.prototype.toString.call(obj)==='[object Array]';  
  129.         };  
  130.   
  131.         /********* 打印Request Headers **********/  
  132.         console.log("\n--->>\nRequest Headers:",req.rawHeaders);  
  133.   
  134.         /***** 向后端发送请求基本的设置 *****/  
  135.         var options={  
  136.               port: 80,  
  137.               host:"code.liuxinxiu.com",  
  138.               path:'/php/Post/CORS_PHP.php',  
  139.               method: 'POST',  
  140.               headers:{  
  141.                   'Content-Type':_self.getReqHeaders('Content-Type'),  
  142.                   'Content-Length':data.length,  
  143.                   'Origin':_self.getReqHeaders('Origin'),  
  144.                   'User-Agent':_self.getReqHeaders('User-Agent')  
  145.               }  
  146.         };  
  147.   
  148.         /***** 如果header整体替换就会乱码 *****/  
  149.         //options.headers=_self.rawHeaders();  
  150.   
  151.   
  152.         var request=http.request(options,function(result){  
  153.               console.log("\n--->>\nstatusCode:",result.statusCode);  
  154.               console.log("\n--->>\nResponse Headers:",result.headers);  
  155.   
  156.               if(result){  
  157.                  var content_type,origin,x_powered_by,server;  
  158.                      //content_type=origin=x_powered_by=server=undefined;  
  159.                      content_type=result.headers['content-type'];  
  160.                      origin=result.headers['access-control-allow-origin'];  
  161.                      x_powered_by=result.headers['x-powered-by'];  
  162.                      server=result.headers['server'];  
  163.   
  164.                      /********** 判断分别加入包含服务器错误页 **********/  
  165.                      if(origin!=undefined&&result.statusCode==200){  
  166.                         res.setHeader('Access-Control-Allow-Origin',origin);  
  167.                      }  
  168.                      if(content_type!=undefined){  
  169.                         res.setHeader('Content-Type',content_type);  
  170.                      }  
  171.                      if(x_powered_by!=undefined){  
  172.                         res.setHeader('X-Powered-By',x_powered_by);  
  173.                      }  
  174.                      if(server!=undefined){  
  175.                         res.setHeader('Server',server);  
  176.                      }  
  177.   
  178.               }  
  179.               /********** 有异常的请求需要问题定位 **********/  
  180.               if(result.statusCode<200||result.statusCode>206){  
  181.               }  
  182.   
  183.               /********** 接受数据数据监听 **********/  
  184.               var _data='';  
  185.               result.on('data',function(chunk){  
  186.                 _data+=chunk;  
  187.               });  
  188.   
  189.               /********** 结束接受数据监听 *********/  
  190.               result.on('end',function(){  
  191.                    console.log("\n--->>\nresult:",_data);  
  192.                    res.write(_data);  
  193.                    res.end();  
  194.               });  
  195.   
  196.         /******** request逻辑完成 ********/  
  197.         });  
  198.   
  199.   
  200.         request.on('error',function(e) {  
  201.               console.log('problem with request: ' + e.message);  
  202.         });  
  203.   
  204.         //request.write(data);  
  205.         request.write(data+"\n");  
  206.         request.end();  
  207.   
  208.     }  
  209.   
  210.   
  211.   
  212.   /****** 内部结束 ******/  
  213.   }  
  214. }  
  215. module.exports=new server();  

NodeJS数据接口(Post请求直接代理至后端PHP): http://liuxinxiu.com:3000/CORS_Node_Proxy/

PHP数据接口(验证跨域提交白名单外返回错误):  http://code.liuxinxiu.com/php/Post/CORS_PHP.php

Tags: , ,

在讨论这个问题之前先了解一下浏览器的缓存机制。浏览器的缓存机制有两种,一种是“Freshness(新鲜度,过期机制)”,另一种是“Validation(校验值,验证机制)”。

 
“Freshness(新鲜度,过期机制)”:缓存副本有效期。若一个缓存副本是有效的、足够新的,则在这段有效期,浏览器直接从缓存中返回数据,无需再次发出实际请求。于是就有了“http 200 from cache”。
 
“Validation(校验值,验证机制)”:http设定了一套校验规则,用来校验当前客户端所缓存的资源是否仍然是新鲜的。当缓存失效时(Freshness优先级高于Validation),浏览器会在请求头中包含前置条件头,再次向服务器发送请求。当校验失效时,说明资源已经被修改或过期,浏览器需求重新获取资源内容。当校验未失效时,会返回“304 not modified”。
 
与缓存有关的http消息报头
 
1.Freshness(新鲜度,过期机制)有关的http消息报头有Cache-Control、Expires、Pragma等。
 
Cache-Control与Expires作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
 
2.Validation(校验值,验证机制)有关的http消息报头有ETag、Last-Modified、If-Modified-Since、If-None-Match、If-Range、Cache-Control等。
 
Last-modified 和 If-Modefied-Since 一起工作。Last-modfied(在request头内) 指的是本地文件的修改时间。 If-Modefied-Since(在response头内)指的是服务器文件的修改时间。当Last-modefied与If-modefied-since一致时,说明文件没有被修改过,返回304,浏览器直接读取缓存中的文件。若不一致,则说明文件被修改过,返回200,浏览器重新从服务器换取文件。
 
If-None-Match 和 ETag 一起工作。 如果If-None-Match 和 ETag 一致,说明文件没有修改,返回304,使用缓存。否则重新从服务器获取文件。
 
既然已经有了 Last-Modified 已经能够知道本地缓存是否是最新的了,为什么还需要 Etag 呢?
 
主要是基于以下几个原因:
 
Last-Modified 标注的最后修改时间只能精确到秒,如果有些资源在一秒之内被多次修改的话,他就不能准确标注文件的新鲜度了
如果某些资源会被定期生成,当内容没有变化,但 Last-Modified 却改变了,导致文件没使用缓存
有可能存在服务器没有准确获取资源修改时间,或者与代理服务器时间不一致的情形。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304
=============================================================
1,Last-Modified
设置 header("Last-Modified: ".gmdate("D, d M Y H:i:s", time() )." GMT"); 
Last-Modified虽然使用了缓存,但是每次打开页面依然需要向服务器发起http请求,浏览器根据用户的$_SERVER['HTTP_IF_MODIFIED_SINCE']来判断浏览器的内容是否过期,没过期的话返回304状态,浏览器内容从缓存中读取
 
2,Expires
设置 header("Expires: ".gmdate("D, d M Y H:i:s", time()+$cache_time )." GMT"); 
状态码依然是200,时间依然是旧的时间,Size栏目显示为from cache,表示内容是直接从浏览器读取,浏览器根本就没有向服务器发起http请求
 
Expires比Last-Modified缓存效果更好是吧,因为本地有缓存数据时,不需要向服务器发起http请求,服务器的并发数会明显的减少,可以少处理很多http请求

 

C#代码
  1. location ~ \.( html|js|css|png|gif|jpg|jpeg|bmp|swf)$ {     
  2.  
  3.     #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到 upstream负载均衡池中的另一台服务器,实现故障转移  
  4.     proxy_next_upstream http_502 http_504 error timeout invalid_header;  
  5.     proxy_cache cache_one;  
  6.  
  7.     #对不同的HTTP状态码设置不同的缓存时间  
  8.     proxy_cache_valid 200 10m;  
  9.     proxy_cache_valid 304 1m;  
  10.     proxy_cache_valid 301 302 1h;  
  11.     proxy_cache_valid any 1m;  
  12.  
  13.     #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希  
  14.     proxy_cache_key $host$uri$is_args$args;  
  15.     proxy_set_header Host $host;  
  16.     proxy_set_header X-Forwarded-For $remote_addr;  
  17.  
  18.     #如果没有缓存则通过proxy_pass转向tomcat请求  
  19.     proxy_pass http://tomcat_server_pool;  
  20.   
  21. }  
Tags: ,

Nginx upstream 相关配置

[不指定 2016/09/16 20:15 | by 刘新修 ]

Nginx_upstream实现:设置备份主机及过滤HTTP错误自动切除[8000=>Node服务器 || 2000=>默认错误处理页]:

C#代码
  1. #集群中的所有后台服务器的配置信息  
  2. upstream nodeJs {  
  3.     #server 123.56.233.208 weight=10;  
  4.     #server 127.0.0.1:3000 weight=10;  
  5.     server 127.0.0.1:8000;  
  6.     server 127.0.0.1:2000 backup;  
  7. }  
  8.  
  9. #调用所有的Server配置文件  
  10. include /usr/local/nginx/conf/vhosts/*.conf;  
  11.   
  12. server {  
  13.     listen 3000;  
  14.     server_name liuxinxiu.com;  
  15.   
  16.     add_header Proxy-By $upstream_http_server; #代理服务器Server  
  17.   
  18.     location / {  
  19.             proxy_pass http://nodeJs; #反向代理到后端Server  
  20.             proxy_set_header Host $host:3000;  
  21.             proxy_set_header X-Real-IP $remote_addr;  
  22.             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
  23.             #proxy_next_upstream error timeout invalid_header http_403 http_404;  
  24.     }  
  25. }  

Nginx=>2000端口默认错误处理页(相关配置):

C#代码
  1. server{  
  2.    listen 2000;  
  3.    server_name  127.0.0.1;  
  4.    index index.html index.htm index.php;  
  5.    root  /ftp/www/2000;  
  6.   
  7.    error_page  404  /index.html;  
  8.   
  9. }  

 

Tags: ,

关于setTimeout传参的思考

[不指定 2016/09/14 16:15 | by 刘新修 ]
JavaScript代码
  1. function countdown(n){  
  2.     //var i=10;if(!n)n=i;  
  3.     function _show(o){  
  4.         return function(){  
  5.             countdown(o);  
  6.         }  
  7.     }    
  8.     if(n>0){  
  9.         console.log(n);n--;  
  10.         setTimeout(_show(n),1000);  
  11.     }  
  12. };countdown(10);  
Tags:

使用NodeJs实现CORS 跨域资源共享,可传参origin通过限制,代码如下:

JavaScript代码
  1. var http=require('http');  
  2. var origin=require('./origin'); //调用白名单列表  
  3.   
  4. function CORS_Node(){  
  5.     this.exec=function(route,req,res){  
  6.     var _self=this;  
  7.   
  8.     /************** 获取客户端origin的域名 **************/  
  9.     origin.req=req;                //白名单设置置请求头  
  10.     origin.yes=origin.listV();     //是否在名单|true  
  11.     origin.name=origin.getName();  //客户端ORIGIN  
  12.   
  13.   
  14.     /******** 先纠正参数,参数正确后匹配白名单 ********/  
  15.   
  16.   
  17.     /********** 判断是GET请求类型 **********/  
  18.     if(req.method.toUpperCase()=="GET"){  
  19.   
  20.         var params=[];  
  21.         //params=url.parse(request.url,true).query;  
  22.         //params['fruit']=compute(params);  
  23.         res.writeHeader(200,{  
  24.             "Content-type":"text/html; charset=utf-8"  
  25.         });  
  26.         res.write('<h1>It is forbidden for the URL request!</h1>');  
  27.         res.write('<hr><address>NodeJs/'+process.version);  
  28.         res.write(' at '+req.headers.host.split(':')[0]);  
  29.         res.write(' Port '+req.headers.host.split(':')[1]+'</address>');  
  30.         res.end();  
  31.   
  32.     }  
  33.     /********* 判断是POST请求类型 **********/  
  34.     else if(req.method.toUpperCase()=='POST'){  
  35.   
  36.         var postData="";  
  37.         /********** 读取Post提交的数据 **********/  
  38.         req.addListener("data",function(data){  
  39.             postData+=data;  
  40.         });  
  41.   
  42.         /********** 数据读取完毕就会执行的监听 *********/  
  43.         req.addListener("end",function(){  
  44.            /********* 定义Post请求主体 *********/  
  45.            var query=require('querystring').parse(postData);  
  46.   
  47.   
  48.            /********** 给客户端返回数据自造JSON **********/  
  49.            function getJson(status){  
  50.                 if(isNaN(status))status=-1;  
  51.                 else{status=Number(status)}  
  52.                 var _drr='{'  
  53.                       +'"status":"1",'  
  54.                       +'"name":"'+query.name+'",'  
  55.                       +'"gender":"'+query.gender+'"}';  
  56.                 var _arr='{'  
  57.                       +'"status":1,'  
  58.                       +'"url":"http://www.liuxinxiu.com/",'  
  59.                       +'"dataList":'  
  60.                       +'{'  
  61.                       +'"siteId":101,'  
  62.                       +'"title":"我的博客||Node Server",'  
  63.                       +'"images":"http://www.liuxinxiu.com/upload/2016/08/10/moren.gif",'  
  64.                       +'"indexNum":"10",'  
  65.                       +'"pageNum":"100000",'  
  66.                       +'"tagNum":"22",'  
  67.                       +'"linkType":"linkTaobao",'  
  68.                       +'"publishTime":"23:15:30"'  
  69.                       +'}'  
  70.                       +'}';  
  71.                 this._dr=JSON.parse(_drr);this._ar=JSON.parse(_arr);  
  72.                 this._dt=this._dr;this._dt.getUser=this._ar;  
  73.            }  
  74.   
  75.            var errStr={"status":-1,"info":"Request Error"};  
  76.   
  77.            /********** 先初步设置头信息,跨域全放开稍后再进行匹配验证 **********/  
  78.            var content_type,content_length,  
  79.            content_type='application/json; charset=utf-8';  
  80.            content_length=Buffer.byteLength(res,'utf8');  
  81.            res.setHeader('Access-Control-Allow-Origin','*');  
  82.            res.setHeader('Access-Control-Allow-Headers','X-Requested-With');  
  83.            res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,OPTIONS');  
  84.            res.setHeader('Content-Type',content_type);  
  85.            res.setHeader('Server','NodeJs/'+process.version);  
  86.   
  87.   
  88.            /************** 判断如果有POST过来规范的数据 *************/  
  89.            if(query.name&&query.gender){  
  90.                 //调用数据  
  91.                 getJson(1);  
  92.   
  93.                 /******** 匹配客户端域名是否在数组列表中 ******/  
  94.                 //if(_self.in_array(origin,allow_origin)){  
  95.                 if(origin.yes){  
  96.                      res.setHeader('Access-Control-Allow-Origin',origin.name);  
  97.                      res.end(JSON.stringify(_dt));  
  98.                 }  
  99.                 else{  
  100.                      /******** 如有设置就取设置URL返回头信息 ********/  
  101.                      if(query.origin){  
  102.                         res.setHeader('Access-Control-Allow-Origin',query.origin);  
  103.                         res.end(JSON.stringify(_dt));  
  104.                      }  
  105.                      /******** 没设置URL就返回无权限错误信息  ********/  
  106.                      else{  
  107.                         errStr.info="You don't have permission to submit!";  
  108.                         res.setHeader('Access-Control-Allow-Origin',origin.name);
  109.                         res.end(JSON.stringify(errStr));
  110.                      }
  111.                 }
  112.            }
  113.            /********* 没有所匹配的POST提交数据||都要设头返回信息 ********/
  114.            else{
  115.                 /******** 其他POST参数的提交  ********/
  116.                 if(query){
  117.                     res.writeHeader(res.statusCode,{
  118.                         "Access-Control-Allow-Origin":origin.name,
  119.                         "Access-Control-Allow-Headers":"X-Requested-With",
  120.                         "Access-Control-Allow-Methods":"GET,POST,PUT,DELETE,OPTIONS",
  121.                         "Content-type":"application/json; charset=utf-8"
  122.                     });
  123.                     var err={status:-1,info:"Syntax error in parameters or arguments."};
  124.                     res.end(JSON.stringify(err));
  125.                 }
  126.                 else{
  127.                     res.writeHeader(res.statusCode,{
  128.                         "Content-type": "text/html; charset=utf-8"
  129.                     });
  130.                     res.end('It is forbidden for the URL request!');  
  131.                 }  
  132.   
  133.             }  
  134.             /****** 判断结束 ******/  
  135.         });  
  136.   
  137.     }  
  138.   
  139.   
  140.   /****** 内部结束 ******/  
  141.   }  
  142. }  
  143. module.exports=new CORS_Node();  

NodeJs数据提交接口地址 (不允许使用GET访问) :http://liuxinxiu.com:3000/CORS_Node/

注意:NodeJs Server 是本站的测试环境,有时候因需要会临时关闭,该地址仅供测试,如您有需要请自建环境~

配合HTML代码如下:

XML/HTML代码
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8"/>    
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />  
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>  
  7.     <meta name="format-detection"content="telephone=no">  
  8.     <meta name="apple-mobile-web-app-capable" content="yes" />  
  9.     <meta name="apple-mobile-web-app-status-bar-style" content="black" />  
  10.     <style>body,html {background:#fff;font-family: "Lucida Grande",Calibri,Arial;font-size:12pt;color: #333;background: #f8f8f8;text-align:center;}*{margin:0;padding:0;}h1{line-height:1.6em;font-size:24px;text-indent:.5em;padding-top:.6em}i{line-height:2em;font-size:18px;color:#999;}.line{height:10px;border-bottom:1px solid #ccc;font-size:0;overflow:hidden;}</style>  
  11.     <title>跨域测试</title>  
  12. </head>  
  13. <body>  
  14. <h1 id="show"></h1>  
  15. <input type="button" value="Click me" onclick="msg()" />  
  16.   
  17. </body>  
  18. <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>  
  19. <script type='text/javascript'>  
  20. /********** 获取URL参数 **********/  
  21. function getQueryString(name){  
  22. var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)","i");  
  23. var r=window.location.search.substr(1).match(reg);  
  24. if (r!=null) return unescape(r[2]); return null;  
  25. }  
  26. var _n=getQueryString('n');  
  27. var _url=getQueryString('url');  
  28. var _name=getQueryString('name');  
  29. var _gender=getQueryString('gender');  
  30. var _origin=getQueryString('origin');  
  31. var _error=getQueryString('error');  
  32. console.log('origin:'+_origin+' —— name:'+_name+' —— gender:'+_gender);  
  33.   
  34. window.onload=function(){  
  35.     if(_n=='php'){  
  36.     location.href='http://'  
  37.              +location.host  
  38.              +location.pathname  
  39.              +'?origin=http://'+location.host;  
  40.     }else if(_n=='node'){  
  41.         location.href='http://'  
  42.                      +location.host  
  43.                      +location.pathname  
  44.                      +'?origin=http://'+location.host+'&'  
  45.              +'url=http://liuxinxiu.com:3000/CORS_Node/'  
  46.   
  47.     }else if(_n=='proxy'){  
  48.         location.href='http://'  
  49.                      +location.host  
  50.                      +location.pathname  
  51.                      +'?origin=http://'+location.host+'&'  
  52.                      +'url=http://liuxinxiu.com:3000/CORS_Node_Proxy/'  
  53.       
  54.     }else if(_n=='test'){  
  55.         location.href='http://test1.liuxinxiu.com/php/Interface/html/server.html'  
  56.              +'?origin=http://test1.liuxinxiu.com&'  
  57.              +'url=http://liuxinxiu.com:3000/CORS_Node_Proxy/&'  
  58.              +'error=1'  
  59.     }  
  60. }  
  61.   
  62. /********** 发起Ajax请求 **********/  
  63. function msg(){  
  64.     /******* 动态切换提交数据 *******/  
  65.     if(_origin&&!_error){  
  66.     if(_name&&_gender){  
  67.         var data={name:_name,gender:_gender,origin:_origin};  
  68.     }  
  69.     else{  
  70.         var data={name:"xiaoming",gender:"male",origin:_origin};  
  71.     }  
  72.     }  
  73.     else if(_error==null){  
  74.     var data={name:"xiaoming",gender:"male"};  
  75.     }  
  76.     else if(_error){  
  77.         var data={xxx:111};  
  78.     }  
  79.     /******* 动态设置提交URL *******/  
  80.     if(_url){  
  81.     var urlPath=_url;  
  82.     }  
  83.     else{  
  84.     var urlPath='http://code.liuxinxiu.com/php/Post/CORS_PHP.php';  
  85.     }  
  86.     $.ajax({  
  87.        type:'post',  
  88.        url:urlPath,  
  89.        data:data,  
  90.        cache:false,  
  91.        dataType:'json',  
  92.        success:function(data){  
  93.            if(data.name){  
  94.         document.getElementById("show").innerHTML=data.name+' '+data.gender;  
  95.            }  
  96.        else if(data.status!=1){  
  97.         document.getElementById("show").innerHTML=data.info;  
  98.        }  
  99.        },    
  100.        error:function(){  
  101.            console.log("请求错误//")  
  102.        }  
  103.     });  
  104. };  
  105.   
  106. /***********************************************************************************************  
  107. $.post("http://www.server.com/server.php",{name:"fdipzone",gender:"male"}).done(function(data){    
  108.     document.getElementById("show").innerHTML=data.name+' '+data.gender;  
  109. });  
  110. **********************************************************************************************/  
  111. </script>  
  112. </html>  

HTML访问地址 (测试跨域) ==> http://test1.liuxinxiu.com/php/Interface/html/server.html?n=node

HTML访问地址 (非法参数) ==> http://test1.liuxinxiu.com/php/Interface/html/server.html?error=node

注意:本站的 NodeJs Server 是学习测试环境,有临时关闭的可能,建议在本地环境测试~

Tags: , ,
第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]