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

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: , ,
JavaScript代码
  1. var a = ['a','b','c'];  
  2. var json = {};  
  3. for(var i=0;i<a.length;i++)  
  4. {  
  5.     json[i]=a[i];  
  6. }  
  7. var jsonStr=JSON.stringify(json);//结果:"{'1':'a','2':'b','3':'c'}"  
  8. var jsonObj=JSON.parse(jsonStr); //结果:[object Object]  

JS Array To Json 加强版:

1. 自然数自动递增并设置K值

2. 取偶数Length为Json数组的K值

JavaScript代码
  1. /******** 获取客户端请求的header整体头部信息 ********/  
  2. this.rawHeaders=function(state){  
  3.     var json={};  
  4.     if(!state){  
  5.         for(var i=0;i<req.rawHeaders.length;i++){  
  6.             var s,s=i;  
  7.             if(i%2==0){  
  8.                 s++;json[req.rawHeaders[i]]=req.rawHeaders[s];  
  9.             }  
  10.         }  
  11.     }  
  12.     if(state){  
  13.         for(var i=0;i<req.rawHeaders.length;i++){  
  14.             json[i]=req.rawHeaders[i];  
  15.         }  
  16.     }  
  17.     var jsonStr=JSON.stringify(json);//结果:"{'1':'a','2':'b','3':'c'}"  
  18.     var jsonObj=JSON.parse(jsonStr); //结果:[object Object]  
  19.     return jsonObj;  
  20. };  

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

PHP代码
  1. <?php  
  2. /******** 定义Response返回header头格式及编码 ********/  
  3. header('Content-type: application/json; charset=utf-8');  
  4.   
  5. /******** 回调参数设置 ********/  
  6. $param="origin";  
  7. $origin_URL=$_REQUEST[$param];  
  8.   
  9.   
  10. /******** json_encode 转成=> encode_json *******/  
  11. function encode_json($str){  
  12.     return urldecode(json_encode(url_encode($str)));  
  13. }  
  14. function url_encode($str){  
  15.     if(is_array($str)){  
  16.         foreach($str as $key=>$value){  
  17.             $str[urlencode($key)]=url_encode($value);  
  18.         }  
  19.     }else{  
  20.         $str=urlencode($str);  
  21.     }  
  22.     return $str;  
  23. }  
  24.   
  25. /**************** \/\/反转义范例 ********************/  
  26. function stripslashes_deep($value){  
  27.     $value=is_array($value)?  
  28.                 array_map('stripslashes_deep',$value):  
  29.                 stripslashes($value);  
  30.     return $value;  
  31. }  
  32.   
  33. /******************** Example ******************************/  
  34. $array=array("f\\'oo", "b\\'ar", array("fo\\'o", "b\\'ar"));  
  35. $array=stripslashes_deep($array);  
  36.   
  37. /******************** Output *******************************/  
  38.   
  39. //echo encode_json(array('china'=>'钓鱼岛是中国的!','Japan'=>array('name'=>'日本狗!')));  
  40.   
  41.   
  42. /************ 定义Post过来什么数据就返回什么数据 ***********/  
  43. $res=array(  
  44.     'status'=>-1,
  45.     'name'=>isset($_POST['name'])?$_POST['name']:'',
  46.     'gender'=>isset($_POST['gender'])?$_POST['gender']:''
  47. );
  48. $arr=array(
  49.      "status"=>1,
  50.      "url"=>"http://www.liuxinxiu.com/",
  51.      "dataList"=>array(
  52.           "siteId"=>"1",
  53.           "title"=>urldecode('我的博客'),
  54.           "images"=>"http://192.168.9.100/upload/2015/06/20/moren.gif",
  55.           "indexNum"=>10,
  56.           "pageNum"=>"300",
  57.           "tagNum"=>"20",
  58.           "linkType"=>"linkTaobao",
  59.           "publishTime"=>"20:00:00"
  60.       )
  61. );
  62. $arr['dataList']['images']="http://www.liuxinxiu.com/upload/2015/06/20/moren.gif";
  63. //print_r($arr);
  64. /*************** 定义错误信息 ***************/
  65. $errStr='{"status":-1,"info":"Request Error"}';
  66. $errJson=json_decode($errStr,true); //json_decode转成了array数组
  67. //print_r($errJson) //转成了array数组
  68. /************** 获取客户端的Origin域名 **************/
  69. $origin=isset($_SERVER['HTTP_ORIGIN'])?$_SERVER['HTTP_ORIGIN']:'';
  70. /******** 定义符合规则的域名数组 ********/
  71. $allow_origin=array(
  72.     'http://liuxinxiu.com',  
  73.     'http://code.liuxinxiu.com',  
  74.     'http://test.liuxinxiu.com'  
  75. );  
  76.   
  77. /****************** 判断如果有POST过来数据 *********************/  
  78. if(isset($_POST['name'])&&isset($_POST['gender'])){
  79.     /********** 只要是POST请求过来无论合法与否都要正常通信 **********/
  80.      header('Access-Control-Allow-Methods:POST');
  81.      header('Access-Control-Allow-Headers:x-requested-with,content-type');
  82.     /******** 匹配客户端域名是否在数组列表中 ******/
  83.     if(in_array($origin,$allow_origin)){
  84.         header('Access-Control-Allow-Origin:'.$origin);
  85.         $res['status']=1;
  86.         $res['getUser']=$arr;
  87.         echo json_encode($res);
  88.     }
  89.     else if(!in_array($origin,$allow_origin)){
  90.         /******** 如有设置就取设置URL返回头信息 ********/
  91.         if(isset($origin_URL)){
  92.             header('Access-Control-Allow-Origin:'.$origin_URL);
  93.             $res['status']=1;
  94.             $res['getUser']=$arr;
  95.             echo encode_json($res);
  96.             //echo json_encode("中文", JSON_UNESCAPED_UNICODE);
  97.         }
  98.         /******** 如没有设置URL就返回错误信息  ********/
  99.         else{
  100.             header('Access-Control-Allow-Origin:'.$origin);
  101.             $errJson['status']=-1;
  102.             $errJson['info']="You don't have permission to submit!";  
  103.             echo encode_json($errJson);  
  104.         }  
  105.     }  
  106. }  
  107. /************ 没有所匹配的POST提交数据 ***********/  
  108. else{  
  109.     if($GLOBALS['HTTP_RAW_POST_DATA']){  
  110.             header('Access-Control-Allow-Origin:'.$origin);  
  111.             $errJson['status']=-1;  
  112.             $errJson['info']="Syntax error in parameters or arguments.";  
  113.             echo encode_json($errJson);  
  114.     }  
  115.     else{  
  116.         header("Content-type: text/html; charset=utf-8");  
  117.         echo 'It is forbidden for the URL request!';  
  118.     }  
  119. }  
  120. ?>  

PHP数据提交接口地址 (禁止使用GET访问):http://code.liuxinxiu.com/php/Interface/server.php

配合HTML代码如下:

XML/HTML代码
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8"/>  
  5.   
  6.     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />  
  7.     <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>  
  8.     <meta name="format-detection"content="telephone=no">  
  9.     <meta name="apple-mobile-web-app-capable" content="yes" />  
  10.     <meta name="apple-mobile-web-app-status-bar-style" content="black" />  
  11.     <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>  
  12.     <title>跨域测试</title>  
  13. </head>  
  14. <body>  
  15. <h1 id="show"></h1>  
  16. <input type="button" value="Click me" onclick="msg()" />  
  17.   
  18. </body>  
  19. <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>  
  20. <script type='text/javascript'>  
  21. /********** 获取URL参数 **********/  
  22. function getQueryString(name){  
  23. var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)","i");  
  24. var r=window.location.search.substr(1).match(reg);  
  25. if (r!=null) return unescape(r[2]); return null;  
  26. }  
  27.   
  28.   
  29. /********** 发起Ajax请求 **********/  
  30. function msg(){  
  31.     /******* 动态切换提交数据 *******/  
  32.     if(_origin){  
  33.         if(_name&&_gender){  
  34.             var data={name:_name,gender:_gender,origin:_origin};  
  35.         }  
  36.         else{  
  37.             var data={name:"xiaoming",gender:"male",origin:_origin};  
  38.         }  
  39.     }  
  40.     else if(_error==null){  
  41.         var data={name:"xiaoming",gender:"male"};  
  42.     }  
  43.     else if(_error){  
  44.         var data={xxx:111};  
  45.     }  
  46.     /******* 动态设置提交URL *******/  
  47.     if(_url){  
  48.         var urlPath=_url;  
  49.     }  
  50.     else{  
  51.         var urlPath='http://code.liuxinxiu.com/php/Interface/server.php';  
  52.     }  
  53.     $.ajax({  
  54.        type:'post',  
  55.        url:urlPath,  
  56.        data:data,  
  57.        cache:false,  
  58.        dataType:'json',  
  59.        success:function(data){  
  60.            if(data.name){  
  61.                 document.getElementById("show").innerHTML=data.name+' '+data.gender;  
  62.            }  
  63.            else if(data.status!=1){  
  64.                 document.getElementById("show").innerHTML=data.info;  
  65.            }  
  66.        },  
  67.        error:function(){  
  68.            console.log("请求错误//")  
  69.        }  
  70.     });  
  71. };  
  72.   
  73. /***********************************************************************************************  
  74. $.post("http://www.server.com/server.php",{name:"fdipzone",gender:"male"}).done(function(data){  
  75.     document.getElementById("show").innerHTML=data.name+' '+data.gender;  
  76. });  
  77. **********************************************************************************************/  
  78. </script>  
  79. </html>  

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

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

Tags: ,

 CORS是一个W3C标准,全称是"跨域资源共享" (Cross-origin resource sharing)

CORS,是一种服务器端的跨域解决方案,这种方案对于跨域的解决代码均在服务器端设置完成。在服务器端接收到客户端的请求后,通过获取到请求的来源站点Origin,如果愿意将资源共享给该站点,则通过设置“Access-Control-Allow-Origin”报头的值为请求的来源站点。浏览器接收到包含资源的响应后,会提取“Access-Control-Allow-Origin”响应报头的值,如果此值为*或者包含的源列表包含请求的源站点,则浏览器会允许JavaScript操作获取的资源;否则,不会操作获取的资源。
 
跨域资源共享(CORS )是一种网络浏览器的技术规范,CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。
 
简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。

以往的解决方案

        以前要实现跨域访问,可以通过JSONP、Flash或者服务器中转的方式来实现,但是现在我们有了CORS。

        CORS与JSONP相比,无疑更为先进、方便和可靠。

        1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

        2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

        3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS(这部分会在后文浏览器支持部分介绍)。

详细内容

        要使用CORS,我们需要了解前端和服务器端的使用方法。

        1、  前端

        以前我们使用Ajax,代码类似于如下的方式:

  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "/hfahe", true);  
  3. xhr.send();  

        这里的“/hfahe”是本域的相对路径。

        如果我们要使用CORS,相关Ajax代码可能如下所示:

  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "http://www.liuxinxiu.com/hfahe", true);  
  3. xhr.send();  

        请注意,代码与之前的区别就在于相对路径换成了其他域的绝对路径,也就是你要跨域访问的接口地址。

        我们还必须提供浏览器回退功能检测和支持,避免浏览器不支持的情况。

  1. function createCORSRequest(method, url) {  
  2.   var xhr = new XMLHttpRequest();  
  3.   if ("withCredentials" in xhr) {  
  4.     // 此时即支持CORS的情况  
  5.     // 检查XMLHttpRequest对象是否有“withCredentials”属性  
  6.     // “withCredentials”仅存在于XMLHTTPRequest2对象里  
  7.     xhr.open(method, url, true);  
  8.    
  9.   } else if (typeof!= "undefined") {  
  10.    
  11.     // 否则检查是否支持XDomainRequest,IE8和IE9支持  
  12.     // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式  
  13.     xhr = new XDomainRequest();  
  14.     xhr.open(method, url);  
  15.    
  16.   } else {  
  17.    
  18.     // 否则,浏览器不支持CORS  
  19.     xhr = null;  
  20.    
  21.   }  
  22.   return xhr;  
  23. }  
  24.    
  25. var xhr = createCORSRequest('GET', url);  
  26. if (!xhr) {  
  27.   throw new Error('CORS not supported');  
  28. }  

        现在如果直接使用上面的脚本进行请求,会看到浏览器里控制台的报错如下:

        错误显示的很明显,这是因为我们还未设置Access-Control-Allow-Origin头。

        2、  服务器

        服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

        HTTP 头的设置方法有很多,http://enable-cors.org/这篇文章里对各种服务器和语言的设置都有详细的介绍,下面我们主要介绍Apache和PHP里的设置方法。

        Apache:Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入以下内容即可:

  1. Header set Access-Control-Allow-Origin *  

        PHP:只需要使用如下的代码设置即可。

  1. <?php  
  2.  header("Access-Control-Allow-Origin:*");  

        以上的配置的含义是允许任何域发起的请求都可以获取当前服务器的数据。当然,这样有很大的危险性,恶意站点可能通过XSS攻击我们的服务器。所以我们应该尽量有针对性的对限制安全的来源,例如下面的设置使得只有http://www.liuxinxiu.com 这个域才能跨域访问服务器的API。

  1. Access-Control-Allow-Origin: http://www.liuxinxiu.com  

浏览器支持情况

Tags:
第一页 上页 4 5 6 7 8 9 10 11 12 13 下页 最后页 [ 显示模式: 摘要 | 列表 ]