Authored by 陈峰

api limit

@@ -26,9 +26,12 @@ const isHuman = (req, res) => { @@ -26,9 +26,12 @@ const isHuman = (req, res) => {
26 26
27 remoteIp = arr[0]; 27 remoteIp = arr[0];
28 } 28 }
  29 + const apiLimitValidate = req.session.apiLimitValidate;
  30 +
  31 + delete req.session.apiLimitValidate;
29 32
30 logger.info('isHuman', remoteIp); 33 logger.info('isHuman', remoteIp);
31 - robotCheckService.removeBlack(remoteIp).then(() => { 34 + return robotCheckService.removeBlack(remoteIp, apiLimitValidate).then(() => {
32 return res.json({ 35 return res.json({
33 code: 200 36 code: 200
34 }); 37 });
@@ -5,7 +5,7 @@ const Promise = require('bluebird'); @@ -5,7 +5,7 @@ const Promise = require('bluebird');
5 const co = Promise.coroutine; 5 const co = Promise.coroutine;
6 const config = global.yoho.config; 6 const config = global.yoho.config;
7 const _ = require('lodash'); 7 const _ = require('lodash');
8 -const humanExpire = 60; 8 +const humanExpire = 3600;
9 9
10 const HeaderModel = require('../../../doraemon/models/header'); 10 const HeaderModel = require('../../../doraemon/models/header');
11 11
@@ -17,13 +17,18 @@ const index = co(function* (channel) { @@ -17,13 +17,18 @@ const index = co(function* (channel) {
17 }; 17 };
18 }); 18 });
19 19
20 -const removeBlack = (remoteIp) => { 20 +const removeBlack = (remoteIp, apiLimitValidate) => {
21 let operations = []; 21 let operations = [];
22 22
23 operations.push(cache.delAsync(`${config.app}:limiter:${remoteIp}`)); 23 operations.push(cache.delAsync(`${config.app}:limiter:${remoteIp}`));
24 24
25 // 验证码之后一小时之内不再限制qps 25 // 验证码之后一小时之内不再限制qps
  26 + if (apiLimitValidate) {
  27 + operations.push(cache.setAsync(`${config.app}:limiter:api:ishuman:${remoteIp}`, 1, humanExpire));
  28 + } else {
26 operations.push(cache.setAsync(`${config.app}:limiter:ishuman:${remoteIp}`, 1, humanExpire)); 29 operations.push(cache.setAsync(`${config.app}:limiter:ishuman:${remoteIp}`, 1, humanExpire));
  30 + }
  31 +
27 _.forEach(config.REQUEST_LIMIT, (val, key) => { 32 _.forEach(config.REQUEST_LIMIT, (val, key) => {
28 operations.push(cache.delAsync(`${config.app}:limiter:${key}:max:${remoteIp}`)); 33 operations.push(cache.delAsync(`${config.app}:limiter:${key}:max:${remoteIp}`));
29 }); 34 });
@@ -4,6 +4,13 @@ @@ -4,6 +4,13 @@
4 <div class="captcha-wrap"> </div> 4 <div class="captcha-wrap"> </div>
5 <a class="btn confirm">确定</a> 5 <a class="btn confirm">确定</a>
6 </div> 6 </div>
  7 + <div class="download">
  8 + <div class="bottom-down">
  9 + <div class="qr-code right"></div>
  10 + <a href="http://itunes.apple.com/us/app/id490655927?ls=1&amp;mt=8" target="_blank" class="down-app-btn down-btns"></a>
  11 + <a href="http://yoho-apps.qiniudn.com/YohoBuy_YOHO.apk" target="_blank" class="down-apk-btn down-btns"></a>
  12 + </div>
  13 + </div>
7 </div> 14 </div>
8 15
9 {{> gee-captcha}} 16 {{> gee-captcha}}
@@ -59,6 +59,7 @@ exports.serverError = () => { @@ -59,6 +59,7 @@ exports.serverError = () => {
59 59
60 const uid = req.user ? req.user.uid : 0; 60 const uid = req.user ? req.user.uid : 0;
61 const udid = _.get(req, 'cookies.udid', 'yoho'); 61 const udid = _.get(req, 'cookies.udid', 'yoho');
  62 + let errorCode = 500;
62 63
63 err = err || { 64 err = err || {
64 code: 500 65 code: 500
@@ -102,7 +103,7 @@ exports.serverError = () => { @@ -102,7 +103,7 @@ exports.serverError = () => {
102 if (err.code === 9999991 || err.code === 9999992) { 103 if (err.code === 9999991 || err.code === 9999992) {
103 let remoteIp = req.yoho.clientIp; 104 let remoteIp = req.yoho.clientIp;
104 105
105 - const isHuman = await cache.getAsync(`${config.app}:limiter:ishuman:${remoteIp}`); 106 + const isHuman = await cache.getAsync(`${config.app}:limiter:api:ishuman:${remoteIp}`);
106 107
107 if (!isHuman) { 108 if (!isHuman) {
108 if (remoteIp.indexOf(',') > 0) { 109 if (remoteIp.indexOf(',') > 0) {
@@ -117,6 +118,7 @@ exports.serverError = () => { @@ -117,6 +118,7 @@ exports.serverError = () => {
117 refer: req.protocol + '://' + req.get('host') + req.originalUrl 118 refer: req.protocol + '://' + req.get('host') + req.originalUrl
118 }); 119 });
119 120
  121 + req.session.apiLimitValidate = true;
120 if (req.xhr) { 122 if (req.xhr) {
121 return res.status(510).json({ 123 return res.status(510).json({
122 code: err.code, 124 code: err.code,
@@ -126,12 +128,13 @@ exports.serverError = () => { @@ -126,12 +128,13 @@ exports.serverError = () => {
126 128
127 return res.redirect(limitPage); 129 return res.redirect(limitPage);
128 } 130 }
  131 + errorCode = 510;
129 } 132 }
130 133
131 if (!res.headersSent) { 134 if (!res.headersSent) {
132 if (req.xhr) { 135 if (req.xhr) {
133 - return res.status(500).json({  
134 - code: 500, 136 + return res.status(errorCode).json({
  137 + code: errorCode,
135 message: '服务器错误!' 138 message: '服务器错误!'
136 }); 139 });
137 } 140 }
@@ -139,7 +142,7 @@ exports.serverError = () => { @@ -139,7 +142,7 @@ exports.serverError = () => {
139 const renderErrPage = (result) => { 142 const renderErrPage = (result) => {
140 result = result || {}; 143 result = result || {};
141 144
142 - res.status(500).render('error/500', { 145 + res.status(errorCode).render(`error/${errorCode}`, {
143 module: 'common', 146 module: 'common',
144 page: 'error', 147 page: 'error',
145 err: err, 148 err: err,
@@ -36,7 +36,6 @@ module.exports = (limiter, policy) => { @@ -36,7 +36,6 @@ module.exports = (limiter, policy) => {
36 logger.debug(results); 36 logger.debug(results);
37 37
38 if (results.human) { // 经过验证码之后1小时有效期内不再验证qps 38 if (results.human) { // 经过验证码之后1小时有效期内不再验证qps
39 - console.log('isHuman');  
40 return Promise.resolve(true); 39 return Promise.resolve(true);
41 } 40 }
42 41
  1 +<div class="wrapper screen">
  2 + <div class="clear wrapper-404">
  3 + <div class="left"><img src="http://static.yohobuy.com/images/v3/index/404.png"></div>
  4 + <div class="right right-tips">
  5 + <p class="text1">服务器繁忙请重试!</p>
  6 + <p class="text2">
  7 + </p>
  8 + <p class="text3"><a href="http://www.yohobuy.com/product/new" class="button">浏览新品</a>&nbsp;&nbsp;<a href="http://www.yohobuy.com/" class="button">返回首页</a></p>
  9 + </div>
  10 + </div>
  11 +</div>
@@ -3,7 +3,7 @@ const $ = require('yoho-jquery'); @@ -3,7 +3,7 @@ const $ = require('yoho-jquery');
3 // 注册ajaxError处理服务端异常 3 // 注册ajaxError处理服务端异常
4 $(document).ajaxError((event, xhr) => { 4 $(document).ajaxError((event, xhr) => {
5 if (xhr.responseJSON) { 5 if (xhr.responseJSON) {
6 - if (xhr.status === 510) { 6 + if (xhr.status === 510 && xhr.responseJSON.data && xhr.responseJSON.data.refer) {
7 window.location.href = xhr.responseJSON.data.refer; 7 window.location.href = xhr.responseJSON.data.refer;
8 } 8 }
9 } 9 }
1 .robot-check-page { 1 .robot-check-page {
2 - height: 400px;  
3 -  
4 .captcha { 2 .captcha {
5 width: 1150px; 3 width: 1150px;
6 margin-left: auto; 4 margin-left: auto;
7 margin-right: auto; 5 margin-right: auto;
8 - margin-top: 150px; 6 + margin-top: 100px;
  7 + }
  8 +
  9 + .download {
  10 + margin-bottom: 100px;
9 } 11 }
10 12
11 .title { 13 .title {
@@ -34,4 +36,32 @@ @@ -34,4 +36,32 @@
34 cursor: pointer; 36 cursor: pointer;
35 letter-spacing: 10px; 37 letter-spacing: 10px;
36 } 38 }
  39 +
  40 + .bottom-down {
  41 + width: 350px;
  42 + margin: 0 auto;
  43 + overflow: hidden;
  44 + padding-top: 34px;
  45 +
  46 + .qr-code {
  47 + width: 130px;
  48 + height: 130px;
  49 + background: url("/download/down-qr-code.png");
  50 + }
  51 +
  52 + .down-btns {
  53 + width: 200px;
  54 + height: 60px;
  55 + display: block;
  56 + }
  57 +
  58 + .down-app-btn {
  59 + margin-bottom: 8px;
  60 + background: url("/download/app-down.png");
  61 + }
  62 +
  63 + .down-apk-btn {
  64 + background: url("/download/apk-down.png");
  65 + }
  66 + }
37 } 67 }