很简单的就解决了button的点击刷新问题,给button加一个type=”button”就解决了
CSS设置文字不能选中
/*设置文字不能被选中 以下为css样式*/
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
CSS设置鼠标为小手手型
css中鼠标放上去变成手型怎么设置:其实就是一个属性的问题,
css的cursor属性
cursor:pointer;
default:标准箭头 //这是默认的样式
pointer:手形光标
wait :等待光标
text:I形光标
vertical-text :水平I形光标
no-drop:不可拖动光标
not-allowed:无效光标
help:帮助光标
all-scroll:三角方向标
move :移动标
crosshair:十字标
有的地方手型用hand,在这里隆重的说明,不要用hand,有些浏览器不支持。
PHP+Javascript实现拖动滑块完成拼图验证码
github地址:https://github.com/binwind8/tncode
重要的文件:
1、tncode.js
/*! tncode 1.2 author:weiyingbin email:277612909@qq.com
//@ object webiste: http://www.39gs.com/archive/259.html
//@ https://github.com/binwind8/tncode
*/
if(!document.getElementByClassName){
function hasClass(elem, cls) {
cls = cls || '';
if (cls.replace(/\s/g, '').length == 0) return false; //当cls没有参数时,返回false
var ret = new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ');
return ret;
}
document.getElementByClassName = function(className,index){
var nodes=document.getElementsByTagName("*");//获取页面里所有元素,因为他会匹配全页面元素,所以性能上有缺陷,但是可以约束他的搜索范围;
var arr=[];//用来保存符合的className;
for(var i=0;i<nodes.length;i++){
if(hasClass(nodes[i],className)) arr.push(nodes[i]);
}
if(!index)index=0;
return index==-1?arr:arr[index];
};
function addClass( elements,cName ){
if( !hasClass( elements,cName ) ){
elements.className += " " + cName;
};
}
function removeClass( elements,cName ){
if( hasClass( elements,cName ) ){
elements.className = elements.className.replace( new RegExp( "(\\s|^)" + cName + "(\\s|$)" )," " ); // replace方法是替换
};
}
}
function appendHTML(o,html) {
var divTemp = document.createElement("div"), nodes = null
, fragment = document.createDocumentFragment();
divTemp.innerHTML = html;
nodes = divTemp.childNodes;
for (var i=0, length=nodes.length; i<length; i+=1) {
fragment.appendChild(nodes[i].cloneNode(true));
}
o.appendChild(fragment);
nodes = null;
fragment = null;
};
var _ajax = function() {};
_ajax.prototype = {
request: function(method, url, callback, postVars) {
var xhr = this.createXhrObject()();
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
(xhr.status === 200) ?
callback.success(xhr.responseText, xhr.responseXML) :
callback.failure(xhr,status);
};
if (method !== "POST"&&postVars) {
url += "?" + this.JSONStringify(postVars);
postVars = null;
}
xhr.open(method, url, true);
xhr.send(postVars);
},
createXhrObject: function() {
var methods = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
],
i = 0,
len = methods.length,obj;
for (; i < len; i++) {
try {
methods[i];
} catch(e) {
continue;
}
this.createXhrObject = methods[i];
return methods[i];
}
throw new Error("ajax created failure");
},
JSONStringify: function(obj) {
return JSON.stringify(obj).replace(/"|{|}/g, "")
.replace(/b:b/g, "=")
.replace(/b,b/g, "&");
}
};
var tncode = {
_obj:null,
_tncode:null,
_img:null,
_img_loaded:false,
_is_draw_bg:false,
_is_moving:false,
_block_start_x:0,
_block_start_y:0,
_doing:false,
_mark_w:50,
_mark_h:50,
_mark_offset:0,
_img_w:240,
_img_h:150,
_result:false,
_err_c:0,
_onsuccess:null,
_bind:function(elm,evType,fn){
//event.preventDefault();
if (elm.addEventListener) {
elm.addEventListener(evType, fn);//DOM2.0
return true;
}else if (elm.attachEvent) {
var r = elm.attachEvent(evType, fn);//IE5+
return r;
}
},
_block_start_move:function(e){
if(tncode._doing||!tncode._img_loaded){
return;
}
e.preventDefault();
var theEvent = window.event || e;
if(theEvent.touches){
theEvent = theEvent.touches[0];
}
console.log("_block_start_move");
var obj = document.getElementByClassName('slide_block_text');
obj.style.display="none";
tncode._draw_bg();
tncode._block_start_x = theEvent.clientX;
tncode._block_start_y = theEvent.clientY;
tncode._doing = true;
tncode._is_moving = true;
},
_block_on_move:function(e){
if(!tncode._doing)return true;
if(!tncode._is_moving)return true;
e.preventDefault();
var theEvent = window.event || e;
if(theEvent.touches){
theEvent = theEvent.touches[0];
}
tncode._is_moving = true;
console.log("_block_on_move");
//document.getElementById('msg').innerHTML = "move:"+theEvent.clientX+";"+theEvent.clientY;
var offset = theEvent.clientX - tncode._block_start_x;
if(offset<0){
offset = 0;
}
var max_off = tncode._img_w - tncode._mark_w;
if(offset>max_off){
offset = max_off;
}
var obj = document.getElementByClassName('slide_block');
obj.style.cssText = "transform: translate("+offset+"px, 0px)";
tncode._mark_offset = offset/max_off*(tncode._img_w-tncode._mark_w);
tncode._draw_bg();
tncode._draw_mark();
},
_block_on_end:function(e){
if(!tncode._doing)return true;
e.preventDefault();
var theEvent = window.event || e;
if(theEvent.touches){
theEvent = theEvent.touches[0];
}
console.log("_block_on_end");
tncode._is_moving = false;
tncode._send_result();
},
_send_result:function(){
var haddle = {success:tncode._send_result_success,failure:tncode._send_result_failure};
tncode._result = false;
var re = new _ajax();
re.request('get',tncode._currentUrl().replace('houtai/assets/js', 'config/libs')+'tn_check.php?tn_r='+tncode._mark_offset,haddle);
},
_send_result_success:function(responseText,responseXML){
tncode._doing = false;
if(responseText=='ok'){
tncode._showmsg('验证成功',1);
tncode._result = true;
document.getElementByClassName('hgroup').style.display="block";
//setTimeout(tncode.hide,2500);
setTimeout(function(){
tncode.hide();
tncode._tncode.style.backgroundColor = "#52d192";
tncode._tncode.style.border = "1px solid #52d192";
tncode._tncode.innerHTML = '验证成功';
},2500);
if(tncode._onsuccess){
tncode._onsuccess();
}
}else{
var obj = document.getElementById('tncode_div');
addClass( obj,'dd');
setTimeout(function(){
removeClass( obj,'dd');
},200);
tncode._result = false;
tncode._showmsg('验证失败');
tncode._err_c++;
if(tncode._err_c>5){
tncode.refresh();
}
}
},
_send_result_failure:function(xhr,status){
},
_draw_fullbg:function(){
var canvas_bg = document.getElementByClassName('tncode_canvas_bg');
var ctx_bg = canvas_bg.getContext('2d');
ctx_bg.drawImage(tncode._img, 0, tncode._img_h*2, tncode._img_w, tncode._img_h, 0, 0, tncode._img_w, tncode._img_h);
},
_draw_bg:function(){
if(tncode._is_draw_bg){
return;
}
tncode._is_draw_bg = true;
var canvas_bg = document.getElementByClassName('tncode_canvas_bg');
var ctx_bg = canvas_bg.getContext('2d');
ctx_bg.drawImage(tncode._img, 0, 0, tncode._img_w, tncode._img_h, 0, 0, tncode._img_w, tncode._img_h);
},
_draw_mark:function(){
var canvas_mark = document.getElementByClassName('tncode_canvas_mark');
var ctx_mark = canvas_mark.getContext('2d');
//清理画布
ctx_mark.clearRect(0,0,canvas_mark.width,canvas_mark.height);
ctx_mark.drawImage(tncode._img, 0, tncode._img_h, tncode._mark_w,tncode._img_h,tncode._mark_offset,0,tncode._mark_w, tncode._img_h);
var imageData = ctx_mark.getImageData(0, 0, tncode._img_w, tncode._img_h);
// 获取画布的像素信息
// 是一个一维数组,包含以 RGBA 顺序的数据,数据使用 0 至 255(包含)的整数表示
// 如:图片由两个像素构成,一个像素是白色,一个像素是黑色,那么 data 为
// [255,255,255,255,0,0,0,255]
// 这个一维数组可以看成是两个像素中RBGA通道的数组的集合即:
// [R,G,B,A].concat([R,G,B,A])
var data = imageData.data;
//alert(data.length/4);
var x = tncode._img_h,y=tncode._img_w;
for(var j = 0; j < x; j++) {
var ii = 1,k1=-1;
for(var k=0;k<y&&k>=0&&k>k1;){
// 得到 RGBA 通道的值
var i = (j*y+k)*4;
k+=ii;
var r = data[i]
, g = data[i+1]
, b = data[i+2];
// 我们从最下面那张颜色生成器中可以看到在图片的右上角区域,有一小块在
// 肉眼的观察下基本都是白色的,所以我在这里把 RGB 值都在 245 以上的
// 的定义为白色
// 大家也可以自己定义的更精确,或者更宽泛一些
if(r+g+b<200) data[i+3] = 0;
else{
var arr_pix = [1,-5];
var arr_op = [250,0];
for (var i =1; i<arr_pix[0]-arr_pix[1]; i++) {
var iiii = arr_pix[0]-1*i;
var op = parseInt(arr_op[0]-(arr_op[0]-arr_op[1])/(arr_pix[0]-arr_pix[1])*i);
var iii = (j*y+k+iiii*ii)*4;
data[iii+3] = op;
}
if(ii==-1){
break;
}
k1 = k;
k = y-1;
ii = -1;
};
}
}
ctx_mark.putImageData(imageData, 0, 0);
},
_reset:function(){
tncode._mark_offset = 0;
tncode._draw_bg();
tncode._draw_mark();
var obj = document.getElementByClassName('slide_block');
obj.style.cssText = "transform: translate(0px, 0px)";
},
show:function(){
var obj = document.getElementByClassName('hgroup');
if(obj){
obj.style.display="none";
}
tncode.refresh();
tncode._tncode = this;
document.getElementById('tncode_div_bg').style.display="block";
document.getElementById('tncode_div').style.display="block";
},
hide:function(){
document.getElementById('tncode_div_bg').style.display="none";
document.getElementById('tncode_div').style.display="none";
},
_showmsg:function(msg,status){
if(!status){
status = 0;
var obj = document.getElementByClassName('tncode_msg_error');
}else{
var obj = document.getElementByClassName('tncode_msg_ok');
}
obj.innerHTML = msg;
var setOpacity = function (ele, opacity) {
if (ele.style.opacity != undefined) {
///兼容FF和GG和新版本IE
ele.style.opacity = opacity / 100;
} else {
///兼容老版本ie
ele.style.filter = "alpha(opacity=" + opacity + ")";
}
};
function fadeout(ele, opacity, speed) {
if (ele) {
var v = ele.style.filter.replace("alpha(opacity=", "").replace(")", "") || ele.style.opacity || 100;
v < 1 && (v = v * 100);
var count = speed / 1000;
var avg = (100 - opacity) / count;
var timer = null;
timer = setInterval(function() {
if (v - avg > opacity) {
v -= avg;
setOpacity(ele, v);
} else {
setOpacity(ele, 0);
if(status==0){
tncode._reset();
}
clearInterval(timer);
}
}, 100);
}
}
function fadein(ele, opacity, speed) {
if (ele) {
var v = ele.style.filter.replace("alpha(opacity=", "").replace(")", "") || ele.style.opacity;
v < 1 && (v = v * 100);
var count = speed / 1000;
var avg = count < 2 ? (opacity / count) : (opacity / count - 1);
var timer = null;
timer = setInterval(function() {
if (v < opacity) {
v += avg;
setOpacity(ele, v);
} else {
clearInterval(timer);
setTimeout(function() {fadeout(obj, 0, 6000);},1000);
}
}, 100);
}
}
fadein(obj, 80, 4000);
},
_html:function(){
var d = document.getElementById('tncode_div_bg');
if(d)return;
var html = '<div class="tncode_div_bg" id="tncode_div_bg"></div><div class="tncode_div" id="tncode_div"><div class="loading">加载中</div><canvas class="tncode_canvas_bg"></canvas><canvas class="tncode_canvas_mark"></canvas><div class="hgroup"></div><div class="tncode_msg_error"></div><div class="tncode_msg_ok"></div><div class="slide"><div class="slide_block"></div><div class="slide_block_text">拖动左边滑块完成上方拼图</div></div><div class="tools"><div class="tncode_close"></div><div class="tncode_refresh"></div><div class="tncode_tips"></div></div></div>';
var bo = document.getElementsByTagName('body');
appendHTML(bo[0],html);
},
_currentUrl:function(){
var list = document.getElementsByTagName('script');
for (var i in list) {
var d=list[i];
if(d.src.indexOf('tn_code')!==-1){//js文件名一定要带这个字符
var arr = d.src.split('tn_code');
return arr[0];
}
}
},
refresh:function(){
var isSupportWebp = !![].map && document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;
var _this = this;
tncode._err_c = 0;
tncode._is_draw_bg = false;
tncode._result = false;
tncode._img_loaded = false;
var obj = document.getElementByClassName('tncode_canvas_bg');
obj.style.display="none";
obj = document.getElementByClassName('tncode_canvas_mark');
obj.style.display="none";
tncode._img = new Image();
var img_url = tncode._currentUrl().replace('houtai/assets/js', 'config/libs')+"tncode.php?t="+Math.random();
if(!isSupportWebp){//浏览器不支持webp
img_url+="&nowebp=1";
}
tncode._img.src = img_url;
tncode._img.onload = function(){
tncode._draw_fullbg();
var canvas_mark = document.getElementByClassName('tncode_canvas_mark');
var ctx_mark = canvas_mark.getContext('2d');
//清理画布
ctx_mark.clearRect(0,0,canvas_mark.width,canvas_mark.height);
tncode._img_loaded = true;
obj = document.getElementByClassName('tncode_canvas_bg');
obj.style.display="";
obj = document.getElementByClassName('tncode_canvas_mark');
obj.style.display="";
};
//alert("Hong Kong ForHarvest Technology and Culture Development Co. Limited".length);
obj = document.getElementByClassName('slide_block');
obj.style.cssText = "transform: translate(0px, 0px)";
obj = document.getElementByClassName('slide_block_text');
obj.style.display="block";
},
init:function(){
var _this = this;
if(!tncode._img){
tncode._html();
var obj = document.getElementByClassName('slide_block');
tncode._bind(obj,'mousedown',_this._block_start_move);
tncode._bind(document,'mousemove',_this._block_on_move);
tncode._bind(document,'mouseup',_this._block_on_end);
tncode._bind(obj,'touchstart',_this._block_start_move);
tncode._bind(document,'touchmove',_this._block_on_move);
tncode._bind(document,'touchend',_this._block_on_end);
var obj = document.getElementByClassName('tncode_close');
tncode._bind(obj,'touchstart',_this.hide);
tncode._bind(obj,'click',_this.hide);
var obj = document.getElementByClassName('tncode_refresh');
tncode._bind(obj,'touchstart',_this.refresh);
tncode._bind(obj,'click',_this.refresh);
var objs = document.getElementByClassName('tncode',-1);
for (var i in objs) {
var o = objs[i];
o.innerHTML = '点击按钮进行验证';
tncode._bind(o,'touchstart',_this.show);
tncode._bind(o,'click',_this.show);
}
}
},
result:function(){
return tncode._result;
},
onsuccess:function(fn){
tncode._onsuccess = fn;
}
};
var $TN = tncode;
var _old_onload = window.onload;
window.onload = function(){
if(typeof _old_onload == 'function'){
_old_onload();
}
tncode.init();
};
2、TnCode.class.php
<?php /*! tncode 1.2 author:weiyingbin email:277612909@qq.com //@ object webiste: http://www.39gs.com/archive/259.html //@ https://github.com/binwind8/tncode */ class TnCode { var $im = null; var $im_fullbg = null; var $im_bg = null; var $im_slide = null; var $bg_width = 240; var $bg_height = 150; var $mark_width = 50; var $mark_height = 50; var $bg_num = 6; var $_x = 0; var $_y = 0; //容错象素 越大体验越好,越小破解难道越高 var $_fault = 3; function __construct(){ //ini_set('display_errors','On'); // error_reporting(0); if(!isset($_SESSION)){ session_start(); } } function make(){ $this->_init(); $this->_createSlide(); $this->_createBg(); $this->_merge(); $this->_imgout(); $this->_destroy(); } function check($offset=''){ if(!$_SESSION['tncode_r']){ return false; } if(!$offset){ $offset = $_REQUEST['tn_r']; } $ret = abs($_SESSION['tncode_r']-$offset)<=$this->_fault; if($ret){ unset($_SESSION['tncode_r']); }else{ $_SESSION['tncode_err']++; if($_SESSION['tncode_err']>10){//错误10次必须刷新 unset($_SESSION['tncode_r']); } } return $ret; } private function _init(){ $bg = mt_rand(1,$this->bg_num); $file_bg = dirname(__FILE__).'/tn_img/bg/'.$bg.'.png'; $this->im_fullbg = imagecreatefrompng($file_bg); $this->im_bg = imagecreatetruecolor($this->bg_width, $this->bg_height); imagecopy($this->im_bg,$this->im_fullbg,0,0,0,0,$this->bg_width, $this->bg_height); $this->im_slide = imagecreatetruecolor($this->mark_width, $this->bg_height); $_SESSION['tncode_r'] = $this->_x = mt_rand(50,$this->bg_width-$this->mark_width-1); $_SESSION['tncode_err'] = 0; $this->_y = mt_rand(0,$this->bg_height-$this->mark_height-1); } private function _destroy(){ imagedestroy($this->im); imagedestroy($this->im_fullbg); imagedestroy($this->im_bg); imagedestroy($this->im_slide); } private function _imgout(){ if(!$_GET['nowebp']&&function_exists('imagewebp')){//优先webp格式,超高压缩率 $type = 'webp'; $quality = 40;//图片质量 0-100 }else{ $type = 'png'; $quality = 7;//图片质量 0-9 } header('Content-Type: image/'.$type); $func = "image".$type; $func($this->im,null,$quality); } private function _merge(){ $this->im = imagecreatetruecolor($this->bg_width, $this->bg_height*3); imagecopy($this->im, $this->im_bg,0, 0 , 0, 0, $this->bg_width, $this->bg_height); imagecopy($this->im, $this->im_slide,0, $this->bg_height , 0, 0, $this->mark_width, $this->bg_height); imagecopy($this->im, $this->im_fullbg,0, $this->bg_height*2 , 0, 0, $this->bg_width, $this->bg_height); imagecolortransparent($this->im,0);//16777215 } private function _createBg(){ $file_mark = dirname(__FILE__).'/tn_img/tn_mark.png'; $im = imagecreatefrompng($file_mark); header('Content-Type: image/png'); //imagealphablending( $im, true); imagecolortransparent($im,0);//16777215 //imagepng($im);exit; imagecopy($this->im_bg, $im, $this->_x, $this->_y , 0 , 0 , $this->mark_width, $this->mark_height); imagedestroy($im); } private function _createSlide(){ $file_mark = dirname(__FILE__).'/tn_img/tn_mark2.png'; $img_mark = imagecreatefrompng($file_mark); imagecopy($this->im_slide, $this->im_fullbg,0, $this->_y , $this->_x, $this->_y, $this->mark_width, $this->mark_height); imagecopy($this->im_slide, $img_mark,0, $this->_y , 0, 0, $this->mark_width, $this->mark_height); imagecolortransparent($this->im_slide,0);//16777215 //header('Content-Type: image/png'); //imagepng($this->im_slide);exit; imagedestroy($img_mark); } } ?>
3、tn_style.css
/*按钮*/ .clear{clear: both;} .tncode{ border: 1px solid #ccc; background-color: white; border-radius: 4px; width: 100%; height: 44px; cursor: pointer; opacity: 1; line-height: 44px; } /*浮层*/ .tncode_div_bg{ width: 100%;height: 100%;position: absolute; top:0; left:0; z-index:1000; background-color: rgba(0,0,0,0.5); opacity:0.3; filter: alpha(opacity=30); background-color:#000; *zoom:1; display: none; } .tncode_div{ display: none; background-color: white; z-index: 1000000; width: 260px;height: 260px; position: absolute; left: 50%;top:50%; margin-top: -130px; margin-left: -130px; border: 1px solid #d1d1d1; border-radius: 2px; overflow: hidden; filter: progid:DXImageTransform.Microsoft.Shadow(color='#969696',Direction=135, Strength=5);/*for ie6,7,8*/ /*background-color: #ccc;*/ -moz-box-shadow:2px 2px 5px #969696;/*firefox*/ -webkit-box-shadow:2px 2px 5px #969696;/*webkit*/ box-shadow:2px 2px 5px #969696;/*opera或ie9*/ } .tncode_div .tncode_canvas_bg{ z-index: 0; } .tncode_div .tncode_canvas_mark{ z-index: 10000; } .tncode_div canvas{ position: absolute; left: 10px; top: 10px; } .tncode_div .loading{ padding-top: 60px; position: absolute; left: 10px; top: 10px; background-color: #ccc; width: 240px; height: 150px; text-align: center; box-sizing:border-box; } .dd{ -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-animation: ddf 0.1s ease-in 0s infinite; -o-animation: ddf 0.1s ease-in 0s infinite; animation: ddf 0.1s ease-in 0s infinite; } @-webkit-keyframes ddf { 0% {-webkit-transform: translate(-8px, 3px);} 20% {-webkit-transform: translate(-3px, 1.5px);} 50% {-webkit-transform: translate(0px, 0px) ;} 70% {-webkit-transform: translate(5px, -1.5px) ;} 100% {-webkit-transform: translate(0px, 0px);} } @-o-keyframes ddf { 0% {-o-transform: translate(-8px, 3px);} 20% {-o-transform: translate(-3px, 1.5px);} 50% {-o-transform: translate(0px, 0px) ;} 70% {-o-transform: translate(5px, -1.5px) ;} 100% {-o-transform: translate(0px, 0px);} } @-moz-keyframes ddf { 0% {-moz-transform: translate(-8px, 3px);} 20% {-moz-transform: translate(-3px, 1.5px);} 50% {-moz-transform: translate(0px, 0px) ;} 70% {-moz-transform: translate(5px, -1.5px) ;} 100% {-moz-transform: translate(0px, 0px);} } @keyframes ddf { 0% {transform: translate(-8px, 3px);} 20% {transform: translate(-3px, 1.5px);} 50% {transform: translate(0px, 0px) ;} 70% {transform: translate(5px, -1.5px) ;} 100% {transform: translate(0px, 0px);} } .hgroup{ z-index: 20000; content: ""; position: absolute; left: -800px; top: 70px; width: 250px; height: 15px; background-color: rgba(255,255,255,.5); -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-animation: searchLights 3s ease-in 0s infinite; -o-animation: searchLights 3s ease-in 0s infinite; animation: searchLights 3s ease-in 0s infinite; } @-webkit-keyframes searchLights { 0% { left: -800px; top: 70px; } to { left: 350px; top: 70px } } @-o-keyframes searchLights { 0% { left: -800px; top: 70px; } to { left: 350px; top: 70px } } @-moz-keyframes searchLights { 0% { left: -800px; top: 70px; } to { left: 350px; top: 70px } } @keyframes searchLights { 0% { left: -800px; top: 70px; } to { left: 350px; top: 70px } } /*拉条*/ .slide,.slide_block,.tools .tncode_close,.tools .tncode_refresh{ background-repeat: no-repeat; background-image: url('../img/tn_icon.png'); } .tncode_msg_ok{ background-color: #24C628; } .tncode_msg_error{ background-color: #DE5145; } .tncode_msg_ok,.tncode_msg_error{ position: absolute; top:136px; left: 10px; width: 240px; /* 同tncode_canvas_bg */ height: 24px; color: #fff; margin: 0; padding: 2px 10px; overflow: visible; background-position: 0px 0px; font-size: 14px; opacity:0; filter: alpha(opacity=0.5); z-index: 10000; text-align: center; } .slide{ position: absolute; top:160px; width: 93.52%; height: 0px; background-color: white; background-size: 100%; margin: 5.39% 3.24%; padding: 0px 0px 13.67%; overflow: visible; background-position: 0px 0px; } .tools{ position: absolute; top:210px; width: 93.52%; height: 0px; background-color: white; background-size: 100%; margin: 5.39% 3.24%; padding: 5px 0px 13.67%; overflow: visible; background-position: 0px 0px; border-top: 1px solid #EEEEEE; } .slide_block{ background-position: 0px 12.9794%; width: 65px; height: 65px; position: absolute; left: 0px; top: 0px; margin: -4.62% 0 0 -2.31%; cursor: pointer; } .slide_block_text{ background-position: 0px 12.9794%; height: 65px; position: absolute; left: 65px; top: 20px; margin: -4.62% 0 0 -2.31%; cursor: pointer; font-size: 14px; color: rgb(136, 148, 157); } .tncode_canvas_bg,.tncode_canvas_mark{ /* width: 240px;*/ } .tools .tncode_close{ background-position: 0 50%; height: 30px; width: 30px; float: left; margin-right: 10px; cursor: pointer; } .tools .tncode_refresh{ background-position: 0 94%; height: 30px; width: 30px; float: left; cursor: pointer; } .tools .tncode_tips{ float: right; } .tools .tncode_tips a{ text-decoration: none; font-size: 10px; color: rgb(136, 148, 157); }
Centos7上搭建SVN服务器并实现自动同步至web目录
前言:
能用Git就尽量用git吧,好处自己百度,有关搭建请参考我的另一篇博客搭建服务器上的GIT并实现自动同步到站点目录(www),这篇博客与git搭建的过程应该是基本一样的
预期目的:
1、仓库放在 /var/svn/ 目录下,并且仓库名为 project
2、创建用户组lsgogroup,该组下添加两个成员lsgoweb1、lsgoweb2,密码直接用用户名,两用户可以checkout代码和提交代码
3、利用SVN的钩子实现当仓库的代码更新的时候自动同步至我们的web目录,在这里,我的web目录在 /home/www/ 下
一、搭建svn环境并创建仓库:
1、安装Subversion:
yum install -y subversion
2、检测是否安装成功(查看svn版本号)
svnserve --version
3、创建版本库
//先建目录 mkdir /var/svn cd /var/svn //创建版本库 svnadmin create /var/svn/project cd project//会看到自动生成的版本库文件 conf db format hooks locks README.txt
至此,svn环境搭建成功。
二、创建用户组及用户:
1、 进入版本库中的配置目录conf,此目录有三个文件: svn服务综合配置文件(svnserve.conf)、 用户名口令文件(passwd)、权限配置文件(authz)。
2、修改权限配置文件:vim authz
#进入文件 vim /chiu/svn/taobao/conf/authz [groups] #给用户分配用户组,格式是 组名=成员1,成员2 admin=admin,chiu user=chiu [/] #给用户组分配权限,格式 @组名=rw (r读权限,w写权限) @admin=rw @user=rw
3、配置用户名命令文件:vim passwd
在passwd文件里面添加以下文件以设置账号密码 [users] andrew=andrew joe=joe harry=harry
4、配置SVN服务综合配置文件svnserve.conf
//找到以下配置项,将前面的#号去掉,然后做相应的配置 anon-access = none //匿名用户访问权限:无 auth-access = write //普通用户访问权限:读、写 password-db = passwd //密码文件 authz-db = authz //权限配置文件 realm = /var/svn/project //版本库所在1
注意:所有以上的配置项都需要顶格,即前面不能预留空格,否则报错
5、启动svn服务:
svnserve -d -r /var/svn
如果提示:
svnserve: E000098: Can't bind server socket: Address already in use
证明现在svn已经被启动了,由于我们修改了配置文件,因此要重启svn服务
//查看svn服务详情 ps aux | grep svn //将svn服务强制停止 其中790为svn服务的ID号,-9是kill的参数 kill -9 790
或者用
killall svnserve
再运行 svnserve -d -r /var/svn,进行启动服务
6、测试服务器:
//我们在web目录测试(/home/www) cd /home/www svn co svn://localhost/project
如果提示:Checked out revision 1. 表示checkout成功
我们添加新文件来测试是否提交成功
cd /home/www touch index.php svn add index.php //成功的话会显示 A index.php svn commit index.php -m "测试提交文件"
假如最后提示:
Adding index.php Transmitting file data . Committed revision 2.
则表示我们svn服务器搭建成功!文件已经能够推送了。
7、本地拉取、推送
在本地首先要安装SVN吧,具体百度。。。
填写信息:
点击ok,提示输入用户名和密码
就填刚才我们创建的lsgoweb1或lsgoweb2,和对应的密码即可。
三、实现svn更新自动同步到web目录:
1、在web目录中checkout版本库
这一步算是比较关键的一步了,当时我搭建的时候试了无数次,就是缺少了这一步。把刚才checkout的版本库删掉,我们来一次比较正式的checkout:
svn co svn://localhost/project /home/www --username lsgoweb1(SVN账号) --password lsgoweb1(SVN密码)
进入/var/svn/project/hooks下,建立post-commit文件:
cd /var/svn/project/hooksvim post-commit//在该文件里添加如下代码,保存 #!/bin/sh #设定环境变量,如果没有设定可能会出现update报错 #设定语言,根据系统语言设置,如果是GBK就设置为LANG=zh_CN.GBKexport LANG=en_US.utf8 SVN_PATH=/usr/bin/svn //这里不用改 WEB_PATH=/home/www //web目录,如果你的不同,可以改 //这里的用户随便一个就好 $SVN_PATH update $WEB_PATH --username 'lsgoweb1' --password 'lsgoweb1' --no-auth-cache
保存退出。
修改post-commit用户为www目录用户
chown root:root post-commit
给post-commit 执行权限:
chmod 755 post-commit
测试post-commit,设置完后直接执行脚本看是否没问题
./post-commit
参考:
centos7.0搭建SVN服务器
CentOS创建SVN 服务器,并且设置自动同步到WEB目录
https://blog.csdn.net/csdn2193714269/article/details/78646869
转载自 http://www.centoscn.com/CentosServer/ftp/2016/0515/7236.html,
CentOS 7 配置 nginx php-fpm 详细教程
CentOS 7 配置 Nginx 的步骤如下:
首先更新 yum,没有安装 yum 的自行安装
yum update
1. 安装 Nginx
yum install nginx
开启 Nginx 并设置开机启动
systemctl start nginx
systemctl enable nginx
完成后,输入 localhost 会显示如下页面,表示安装成功,该页面会由两个信息,一个是配置文件的路径,一个是 www 目录的路径
2. 安装最新版本的 PHP、PHP-FPM
注意 PHP 与 PHP-FPM 版本必须保持一致
yum install php php-fpm php-mysql php-devel php-gd php-pecl-memcache php-pspell php-snmp php-xmlrpc php-xml php-pdo
php-pgsql php-pecl-redis php-soap
安装成功后,运行如下命令查看 php 版本
php -v
默认的 php-fpm 安装成功后,/var/run/php-fpm 下会有一个文件 php-fpm.pid
3. 配置 nginx 解析 php
1)修改 nginx 配置文件
vim /etc/nginx/nginx.conf
在 server 中插入如下代码:
location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; ###Save user landing page to cookie: srcid for PHP files ##add_header Set-Cookie $srcid; }
使用如下站点配置指令就可以支持 URL 美化:
location / { try_files $uri $uri/ /index.php?$query_string; }
2) 修改 php-fpm 配置文件
vim /etc/php-fpm.d/www.conf
找到以下三行代码并修改如下
user = nginx
group = nginx
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nignx listen.group = nginx listen.mode = 0660
如果没有配置这一步,浏览器打开 php 文件会报错
“The page you are looking for is temporarily unavailable. Please try again later”
3)修改 php.ini
vim /etc/php.ini
找到 cgi.fix_pathinfo 并修改为 0
cgi.fix_pathinfo=0
以上配置完成后,重启 nginx、php-fpm
systemctl restart php-fpm nginx
测试配置是否成功
vim /usr/share/nginx/html/test.php
<?php // test script for CentOS/RHEL 7+PHP 7.2+Nginx phpinfo(); ?>
在浏览器打开 lcoalhost/test.php
资料参考:
查看网页大小
一个网页的大小会影响打开的速度,所以了解某个网页的大小可以对其进行优化,也可以在计算服务器带宽时作为参考依据。
依次按照以下步骤操作,即可查看网页大小:
用谷歌浏览器打开想要查看的网页→按F12键→再按F5刷新页面,再右侧就会出现代码形式的窗口,如图:
在最底部的会看到一个12.2transferred,这个数值就是网页的大小。
如果使用的是其他浏览器,则步骤需要多一些。
常见的互联网资质
互联网时代必然少不了互联网的资质,作为一家互联网企业,可能会涉及到的资质会有哪些呢?我们一起来看看
经营性ICP许可证
ICP经营许可证是通过互联网向上网用户提供有偿信息、网上广告、代制作网页、电子商务及其它网上应用服务的公司必须办理的网络经营许可证。凡是涉及互联网经营行为的网站都需要办理icp经营许可证。如果是非经营性的网站,只需做好网站域名即可。
SP经营许可证
利用运营商渠道,短信、彩信、彩铃、WAP、铃声下载、手机游戏、位置服务、JAVA/BREW、手机报、商业信息、定位信息等业务的企业,必须申请移动增值业务SP许可证。
网络视听许可证
网络视听经营许可证是经批准设立的广播电台、电视台或依法享有互联网新闻发布资格的网站可以申请开办信息网络传播新闻类视听节目业务的许可证。
网络文化经营许可证
通过向上网用户提供互联网文化产品及其服务活动获取利益的企业,都需办理网络文化经营许可证。主要类目有:音像制品、游戏产品、演出剧(节)目、艺术品、动画等其他文化产品。
提供互联网文化产品及其服务的活动,主要包括:
1)、互联网文化产品的制作、复制、进口、批发、零售、出租、播放等活动;
2)、将文化产品登载在互联网上,或者通过互联网发送到计算机、固定电话机、移动电话机、收音机、电视机、游戏机等用户端,供上网用户浏览、阅读、欣赏、点播、使用或者下载的传播行为;
3)、互联网文化产品的展览、比赛等活动。
互联网出版经营许可证
从事互联网出版业务,就需要申请互联网出版许可证办理。互联网出版业务,是指互联网信息服务提供者将自己创作或他人创作的作品经过选择和编辑加工,登载在互联网上或者通过互联网发送到用户端,供公众浏览、阅读、使用或者下载的在线传播行为。
互联网药品信息服务经营许可证
互联网药品信息服务分为经营性和非经营性两类。凡是通过互联网向上网用户有偿提供药品信息等服务的活动,需要办理互联网药品信息服务经营许可证。
互联网药品交易服务许可证
互联网药品交易服务,是指通过互联网提供药品(包括医疗器械、直接接触药品的包装材料和容器)交易服务的电子商务活动,企业从事该方面服务就需要申请互联网药品交易服务许可证。
互联网医疗保健服务许可证
互联网医疗保健信息服务分为经营性和非经营性两类。网站向上网用户有偿提供医疗保健信息等服务的活动,需要办理互联网医疗保健服务许可证。
呼叫中心经营许可证
呼叫中心许可证是第二类增值电信业务经营许可证中关于呼叫中心业务的资质许可证。如果企业有一定的实力,同时有开展呼叫中心业务的必要,那么该公司就需要申请呼叫中心经营许可证。
关于服务器并发量的简单计算
最简单的计算方式就是根据服务器带宽与页面的大小
1.假设机房带宽为10Mbs,页面的大小为20KB(包含所有的js、css、图片)
同时并发量的理论值: 10*1024/(8*20) = 64个请求/秒
理论上1秒钟同时可以有64个请求访问页面。
注意:10Mbs是位(b),1个字节8位,所以要除8。
2. 假设进来的人是匀速的增加,
根据”三秒定律”(页面打开速度不超过3秒),可得出并发量在单位时间内应是192个请求;
一分钟的请求量在3840。
3.根据二八定律,即80%的访问量发生在20%的时间里
3840*24*60*0.2/0.8=1382400 人次
而发生在每天的高峰期(大约5小时)内的在线人次在110万人次,一个小时为22W人次。
4.当然以上的计算都是理论值,如每个访问者停留页面的平均时间为1分钟左右,访问者的进入和退出都是比较符合正态分布.。
如果是特殊情况服务器肯定是支撑不了这么多人的,例如同一时间有大批量的访问者进入,例如考试系统。又或者同时刷新页面。
而且在实际过程中,现在的页面都肯定超过20KB,那么对带宽的要求也就更大,还有同一个局域网访问情况也要考虑。
以笔者的实际项目来说,我的项目是考试系统。出现过2次比较极端的情况。
本考试系统,登陆的页面容量比较大,所有的js,css以及图片未优化前在400KB左右,我们就以400KB为基准,所有后面要用的文件是在首页一次性加载下来的。
我用的是2台服务器,均为10Mbs带宽。 按照上面的计算方式可得出
2台服务器单位时间内应可以处理19个请求,一天能承载的测评人次是14W左右,而发生在每天的峰值时间(大约5小时)内在线人次在11W左右。
高峰期一个小时的在线人次在2.2W左右。
第一次我们测评人数是7949人,而这些测评者主要使用的是自己的手机分散测评,测评的时间线如下
高峰期是在11点期间,而从这一个小时的日志中查到与实际的服务器数据库的写入人次是17783人次(测评系统的特点是除了极少的几个页面不参数数据库数据写入,其他都是要写入答案或者个人信息)。这一天的测评情况非常顺利,服务器没有任何压力。
第二次,总共只测了2433人,但其中有1200人左右是在局域网且同时登陆系统,第一次导致其中一台机器几乎卡死,后来查看服务器日志,发现瞬时峰值有150个请求/秒,并且我是将所有的静态资源如 JS\CSS\图片都存放在一台服务器中的,也导致这台服务器的带宽一直很高。为了解决这个问题,只好每隔10秒登陆200个考生,一分钟内全部登陆完毕,后面1200人同时进行测评没有任何问题。主要瓶颈就是集中登陆环节。第一次出现问题的时间是下午13点,第二次分批次登陆是17点。测评的时间线如下
而这2个时间段的测评人次分别是和。
可以看出,出问题的时段,与数据库交互的次数其实很少,而下午17点有近27000次的交互,由此也可以得出主要瓶颈就是集中登陆系统导致的,而实际的数据也符合上面的通过计算得出的结果。
✿ 另一种计算方法——服务器并发量分为:1.业务并发用户数;2.最大并发访问数;3.系统用户数;4.同时在线用户数;
并发的意思是指网站在同一时间访问的人数,人数越大,瞬间带宽要求更高。服务器并发量分为:1.业务并发用户数;2.最大并发访问数;3.系统用户数;4.同时在线用户数;
假设一个OA系统有1000用户,这是系统用户数;最高峰同时有500人在线,是“同时在线人数”,也称作“最大业务并发用户数”;500个同时使用系统用户中20%查看系统公告,不构成压力;20%填写表格(只在提交时才会请求,填写对服务器不构成压力);40%在发呆(什么都没做);20%用户不停从一个页面跳转另一个页面(只有这20%对服务器产生了压力)。
说明服务器实际压力,能承受的最大并发访问数,既取决于业务并发用户数,还取决于用户的业务场景,这些可以通过对服务器日志的分析得到。
一般只需要分析出典型业务(用户常用,最关注的业务操作)
给出一个估算业务并发用户数的公式(测试人员一般只关心业务并发用户数)
C=nL/T
C^=C+3×(C的平方根)
C是平均的业务并发用户数、n是login session的数量、L是login session的平均长度、T是指考察的时间段长度、C^是指业务并发用户数的峰值。
该公式的得出是假设用户的login session产生符合泊松分布而估算得到。
假设OA系统有1000用户,每天400个用户发访问,每个登录到退出平均时间2小时,在1天时间内用户只在8小时内使用该系统。
C=400×2/8=100
C^=100+3×(100的平方根)=100+3×10=130
另外,如果知道平均每个用户发出的请求数u,则系统吞吐量可以估算为u×C
请注意:精确估算,还要考虑用户业务操作存在一定的时间集中性(比如上班后1小时内是OA系统高峰期),采用公式计算仍然会存在偏差。针对例子OA系统可以把1小时设定为考察时间的粒度,将一天8小时划分为8个区间,这样可以解决业务操作存在集中性问题,更趋于精准,偏差更小。
原文链接:https://www.cnblogs.com/zhuiyue82/p/11451311.html
参考:https://blog.csdn.net/cardinalzbk/article/details/50822898
https://www.zhihu.com/question/39608108/answer/82173112
TPS和QPS 并发量区别:日活 访问量 活跃度
一、系统承载吞度量
系统的吞度量(承压能力)与request对CPU的消耗、外部接口、IO等等紧密关联。
单个reqeust 对CPU消耗越高,外部系统接口、IO影响速度越慢,系统吞吐能力越低,反之越高。
系统吞吐量几个重要参数:QPS、TPS、并发数、响应时间
1、吞吐量(TPS):吞吐量是指系统在单位时间内处理请求的数量;也就是事务数/秒。它是软件测试结果的测量单位。
2、每秒查询率QPS(TPS):每秒钟request/事务 数量;是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。(一次事务查询T 可能进行了多次服务器请求Q)
3、并发数: 系统同时处理的request/事务数4、并发用户数:并发用户数是指系统可以同时承载的正常使用系统功能的用户的数量;与吞吐量相比,并发用户数是一个更直观但也更笼统的性能指标。5、响应时间(RT):响应时间是指系统对请求作出响应的时间;一般取平均响应时间
二、 日活 访问量 活跃度
1、PV(Page View):
访问量, 即页面浏览量或点击量,衡量网站用户访问的网页数量;在一定统计周期内用户每打开或刷新一个页面就记录1次,多次打开或刷新同一页面则浏览量累计。
2、UV(Unique Visitor):
独立访客,统计1天内访问某站点的用户数(以cookie为依据);访问网站的一台电脑客户端为一个访客。可以理解成访问某网站的电脑的数量。网站判断来访电脑的身份是通过来访电脑的cookies实现的。如果更换了IP后但不清除cookies,再访问相同网站,该网站的统计中UV数是不变的。如果用户不保存cookies访问、清除了cookies或者更换设备访问,计数会加1。00:00-24:00内相同的客户端多次访问只计为1个访客。
3、IP(Internet Protocol):
独立IP数,是指1天内多少个独立的IP浏览了页面,即统计不同的IP浏览用户数量。同一IP不管访问了几个页面,独立IP数均为1;不同的IP浏览页面,计数会加1。 IP是基于用户广域网IP地址来区分不同的访问者的,所以,多个用户(多个局域网IP)在同一个路由器(同一个广域网IP)内上网,可能被记录为一个独立IP访问者。如果用户不断更换IP,则有可能被多次统计。
4、UIP(Unique IP):
独立IP,和UV类似,正常情况下,同一个IP可能会有很多个UV,同一个UV只能有一个IP.
5、VV(Visit View):
访问次数,是指统计时段内所有访客的PV总和。6、CPC(Cost PerClick):
每次点击费用,即点击单价。
7、CPM(Cost Per Mile):
千次展示费用,即广告展示一千次需要支付的费用。
8、RPM(Revenue PerMille):
千次展示收入,和CPM类似,RPM是针对广告展示商(比如Adsense商户)而言的。
9、CTR(Click-throughRate):
点击率,点击次数占展示次数的百分比。
10、DAU(Daily Active User):日活跃用户数量。常用于反映网站、互联网应用运营情况。
11、MAU(monthly active users):月活跃用户人数。
12、PCU(Peak concurrent users):最高同时在线数。
13、DNU: 日新增用户
14、WAU: 是周活跃用户数量
15、ACU: (Average concurrent users)平均同时在线数。
DAU 与 日UV 的区别:
1、UV:没有时间范围限制,就是访问用户数(去重),所以一般会加上每日UV,现在一般都指PC站的访问用户数;
2、DAU:加了时间限制,就是指每日访问用户数(去重),现在一般都会指的是APP的日活用户数。
3、DAU相关指标DAU-DNU 4、DNU/DAU叫这个指标为活跃度指数,当然大家喜欢叫做新增用户占比。