HappyLifeLife.com
HappyLifeLife.com
HappyLifeLife.com 登录 HappyLifeLife.com 注册 HappyLifeLife.com
爱新闻 爱生活
爱分享 爱学习
爱读书 爱探索
爱音乐 爱宇宙
爱电影 爱地球
爱阅读 爱世界
爱运动 爱科技
爱学习

<< < - > >>
Web
Web开发
www.HappyLiveLife.com 收藏 www.happylivelife.com
HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com
编辑
localhost、127.0.0.1、本机ip、0.0.0.0 的区别vue-cli生成的项目在config/index.js中有个host属性,默认配置是0.0.0.0,这时同局域网下的其他机器可以通过本机ip访问服务,改成localhost或者127.0.0.1后就无法访问原理:1. 127.0.0.1一般分配给loopback接口。loopback是个特殊的网络接口(可理解为虚拟网卡),用于本机各个应用之间的网络交互。只要操作系统的网络组件正常,loopback就能工作。linux中查看信息:```lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host```事实上整个127.网段都能用,ping都能通。使用127.0.0.1作为loopback的默认地址是个惯例。当ip层收到目的地址为127.0.0.1的数据包时,不调用网卡进行二次封装,而是立即转到本机ip层进行处理,因此ping 127.0.0.1一般作为测试本机tcp/ip协议栈是否正常。结论:绑定到127.0.0.1的服务只能被本机访问2. localhost是个域名,一般指向127.0.0.1这个ip,操作系统支持ipv6后,也同时指向::1。结论:绑定到localhost的服务也只能被本机访问。如果修改了host让localhost指向就本机ip,那就能被局域网其他机器访问。3.本机地址,指的是本机物理网卡所绑定的网络协议地址,一般指ipv4协议。如果主机有多个网卡,分别连接不同的物理网络,比如192.168.0.1/255.255.255.0 和 192.168.1.1/255.255.255.0,如果服务端socket绑到192.168.0.1,那么192.168.1.1的网段是无法连接的。结论:绑定到本机地址的服务能被同网段其他机器访问4. 0.0.0.0 代表本机的所有ip地址```server.listen({ host: '0.0.0.0', port: 7047});```实际 127.0.0.1 和 本地地址 都绑定了结论:同网段其他机器也可以访问的 点击上传
只能上传jpg/jpeg/png文件,且不超过500kb
data() { fileList: [], logo: '',}methods: { onBeforeUploadImage(file) { const isIMAGE = file.type === 'image/jpeg' || 'image/jpg' || 'image/png' const isLt1M = file.size / 1024 / 1024 < 1 if (!isIMAGE) { this.$message.error('上传文件只能是图片格式!') } if (!isLt1M) { this.$message.error('上传文件大小不能超过 1MB!') } return isIMAGE && isLt1M }, UploadImage(param){ const formData = new FormData() formData.append('file', param.file) UploadImageApi(formData).then(response => { console.log('上传图片成功') param.onSuccess() // 上传成功的图片会显示绿色的对勾 // 但是我们上传成功了图片, fileList 里面的值却没有改变,还好有on-change指令可以使用 }).catch(response => { console.log('图片上传失败') param.onError() }) }, fileChange(file){ this.$refs.upload.clearFiles() //清除文件对象 this.logo = file.raw // 取出上传文件的对象,在其它地方也可以使用 this.fileList = [{name: file.name, url: file.url}] // 重新手动赋值filstList, 免得自定义上传成功了, 而fileList并没有动态改变, 这样每次都是上传一个对象 },}
element-ui表格高亮默认颜色.el-table__body tr.current-row > td {/ background: #edf7ff; /background: #20a0ff;color: #ffffff;}theme = { // 全图默认背景 // backgroundColor: 'rgba(0,0,0,0)', // 默认色板 color: ['#ff7f50','#87cefa','#da70d6','#32cd32','#6495ed', '#ff69b4','#ba55d3','#cd5c5c','#ffa500','#40e0d0', '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700', '#6699FF','#ff6666','#3cb371','#b8860b','#30e0e0'], // 图表标题 title: { x: 'left', // 水平安放位置,默认为左对齐,可选为: // 'center' | 'left' | 'right' // | {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' | 'bottom' | 'center' // | {number}(y坐标,单位px) //textAlign: null // 水平对齐方式,默认根据x设置自动调整 backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 标题边框颜色 borderWidth: 0, // 标题边框线宽,单位px,默认为0(无边框) padding: 5, // 标题内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 主副标题纵向间隔,单位px,默认为10, textStyle: { fontSize: 18, fontWeight: 'bolder', color: '#333' // 主标题文字颜色 }, subtextStyle: { color: '#aaa' // 副标题文字颜色 } }, // 图例 legend: { orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // 'horizontal' | 'vertical' x: 'center', // 水平安放位置,默认为全图居中,可选为: // 'center' | 'left' | 'right' // | {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' | 'bottom' | 'center' // | {number}(y坐标,单位px) backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 图例边框颜色 borderWidth: 0, // 图例边框线宽,单位px,默认为0(无边框) padding: 5, // 图例内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 itemWidth: 20, // 图例图形宽度 itemHeight: 14, // 图例图形高度 textStyle: { color: '#333' // 图例文字颜色 } }, // 值域 dataRange: { orient: 'vertical', // 布局方式,默认为垂直布局,可选为: // 'horizontal' | 'vertical' x: 'left', // 水平安放位置,默认为全图左对齐,可选为: // 'center' | 'left' | 'right' // | {number}(x坐标,单位px) y: 'bottom', // 垂直安放位置,默认为全图底部,可选为: // 'top' | 'bottom' | 'center' // | {number}(y坐标,单位px) backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 值域边框颜色 borderWidth: 0, // 值域边框线宽,单位px,默认为0(无边框) padding: 5, // 值域内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 itemWidth: 20, // 值域图形宽度,线性渐变水平布局宽度为该值 10 itemHeight: 14, // 值域图形高度,线性渐变垂直布局高度为该值 10 splitNumber: 5, // 分割段数,默认为5,为0时为线性渐变 color:['#1e90ff','#f0ffff'],//颜色 //text:['高','低'], // 文本,默认为数值文本 textStyle: { color: '#333' // 值域文字颜色 } }, toolbox: { orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // 'horizontal' | 'vertical' x: 'right', // 水平安放位置,默认为全图右对齐,可选为: // 'center' | 'left' | 'right' // | {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' | 'bottom' | 'center' // | {number}(y坐标,单位px) color : ['#1e90ff','#22bb22','#4b0082','#d2691e'], backgroundColor: 'rgba(0,0,0,0)', // 工具箱背景颜色 borderColor: '#ccc', // 工具箱边框颜色 borderWidth: 0, // 工具箱边框线宽,单位px,默认为0(无边框) padding: 5, // 工具箱内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css itemGap: 10, // 各个item之间的间隔,单位px,默认为10, // 横向布局时为水平间隔,纵向布局时为纵向间隔 itemSize: 16, // 工具箱图形宽度 featureImageIcon : {}, // 自定义图片icon featureTitle : { mark : '辅助线开关', markUndo : '删除辅助线', markClear : '清空辅助线', dataZoom : '区域缩放', dataZoomReset : '区域缩放后退', dataView : '数据视图', lineChart : '折线图切换', barChart : '柱形图切换', restore : '还原', saveAsImage : '保存为图片' } }, // 提示框 tooltip: { trigger: 'item', // 触发类型,默认数据触发,见下图,可选为:'item' | 'axis' showDelay: 20, // 显示延迟,添加显示延迟可以避免频繁切换,单位ms hideDelay: 100, // 隐藏延迟,单位ms transitionDuration : 0.4, // 动画变换时间,单位s backgroundColor: 'rgba(0,0,0,0.7)', // 提示背景颜色,默认为透明度为0.7的黑色 borderColor: '#333', // 提示边框颜色 borderRadius: 4, // 提示边框圆角,单位px,默认为4 borderWidth: 0, // 提示边框线宽,单位px,默认为0(无边框) padding: 5, // 提示内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css axisPointer : { // 坐标轴指示器,坐标轴触发有效 type : 'line', // 默认为直线,可选为:'line' | 'shadow' lineStyle : { // 直线指示器样式设置 color: '#48b', width: 2, type: 'solid' }, shadowStyle : { // 阴影指示器样式设置 width: 'auto', // 阴影大小 color: 'rgba(150,150,150,0.3)' // 阴影颜色 } }, textStyle: { color: '#fff' } }, // 区域缩放控制器 dataZoom: { orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // 'horizontal' | 'vertical' // x: {number}, // 水平安放位置,默认为根据grid参数适配,可选为: // {number}(x坐标,单位px) // y: {number}, // 垂直安放位置,默认为根据grid参数适配,可选为: // {number}(y坐标,单位px) // width: {number}, // 指定宽度,横向布局时默认为根据grid参数适配 // height: {number}, // 指定高度,纵向布局时默认为根据grid参数适配 backgroundColor: 'rgba(0,0,0,0)', // 背景颜色 dataBackgroundColor: '#eee', // 数据背景颜色 fillerColor: 'rgba(144,197,237,0.2)', // 填充颜色 handleColor: 'rgba(70,130,180,0.8)' // 手柄颜色 }, // 网格 grid: { x: 80, y: 60, x2: 80, y2: 60, // width: {totalWidth} - x - x2, // height: {totalHeight} - y - y2, backgroundColor: 'rgba(0,0,0,0)', borderWidth: 1, borderColor: '#ccc' }, // 类目轴 categoryAxis: { position: 'bottom', // 位置 nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' boundaryGap: true, // 类目起始和结束两端空白策略 axisLine: { // 坐标轴线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle控制线条样式 color: '#48b', width: 2, type: 'solid' } }, axisTick: { // 坐标轴小标记 show: true, // 属性show控制显示与否,默认不显示 interval: 'auto', // onGap: null, inside : false, // 控制小标记是否在grid里 length :5, // 属性length控制线长 lineStyle: { // 属性lineStyle控制线条样式 color: '#333', width: 1 } }, axisLabel: { // 坐标轴文本标签,详见axis.axisLabel show: true, interval: 'auto', rotate: 0, margin: 8, // formatter: null, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, splitLine: { // 分隔线 show: true, // 默认显示,属性show控制显示与否 // onGap: null, lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 color: ['#ccc'], width: 1, type: 'solid' } }, splitArea: { // 分隔区域 show: false, // 默认不显示,属性show控制显示与否 // onGap: null, areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] } } }, // 数值型坐标轴默认参数 valueAxis: { position: 'left', // 位置 nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 boundaryGap: [0, 0], // 数值起始和结束两端空白策略 splitNumber: 5, // 分割段数,默认为5 axisLine: { // 坐标轴线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle控制线条样式 color: '#48b', width: 2, type: 'solid' } }, axisTick: { // 坐标轴小标记 show: false, // 属性show控制显示与否,默认不显示 inside : false, // 控制小标记是否在grid里 length :5, // 属性length控制线长 lineStyle: { // 属性lineStyle控制线条样式 color: '#333', width: 1 } }, axisLabel: { // 坐标轴文本标签,详见axis.axisLabel show: true, rotate: 0, margin: 8, // formatter: null, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, splitLine: { // 分隔线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 color: ['#ccc'], width: 1, type: 'solid' } }, splitArea: { // 分隔区域 show: false, // 默认不显示,属性show控制显示与否 areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] } } }, polar : { center : ['50%', '50%'], // 默认全局居中 radius : '75%', startAngle : 90, splitNumber : 5, name : { show: true, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, axisLine: { // 坐标轴线 show: true, // 默认显示,属性show控制显示与否 lineStyle: { // 属性lineStyle控制线条样式 color: '#ccc', width: 1, type: 'solid' } }, axisLabel: { // 坐标轴文本标签,详见axis.axisLabel show: false, textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, splitArea : { show : true, areaStyle : { color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] } }, splitLine : { show : true, lineStyle : { width : 1, color : '#ccc' } } }, // 柱形图默认参数 bar: { barMinHeight: 0, // 最小高度改为0 // barWidth: null, // 默认自适应 barGap: '30%', // 柱间距离,默认为柱形宽度的30%,可设固定值 barCategoryGap : '20%', // 类目间柱形距离,默认为类目间距的20%,可设固定值 itemStyle: { normal: { // color: '各异', barBorderColor: '#fff', // 柱条边线 barBorderRadius: 0, // 柱条边线圆角,单位px,默认为0 barBorderWidth: 1, // 柱条边线线宽,单位px,默认为1 label: { show: false // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } }, emphasis: { // color: '各异', barBorderColor: 'rgba(0,0,0,0)', // 柱条边线 barBorderRadius: 0, // 柱条边线圆角,单位px,默认为0 barBorderWidth: 1, // 柱条边线线宽,单位px,默认为1 label: { show: false // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } } }, // 折线图默认参数 line: { itemStyle: { normal: { // color: 各异, label: { show: false // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle: { width: 2, type: 'solid', shadowColor : 'rgba(0,0,0,0)', //默认透明 shadowBlur: 5, shadowOffsetX: 3, shadowOffsetY: 3 } }, emphasis: { // color: 各异, label: { show: false // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } }, //smooth : false, //symbol: null, // 拐点图形类型 symbolSize: 2, // 拐点图形大小 //symbolRotate : null, // 拐点图形旋转控制 showAllSymbol: false // 标志图形默认只有主轴显示(随主轴标签间隔隐藏策略) }, // K线图默认参数 k: { // barWidth : null // 默认自适应 // barMaxWidth : null // 默认自适应 itemStyle: { normal: { color: '#fff', // 阳线填充颜色 color0: '#00aa11', // 阴线填充颜色 lineStyle: { width: 1, color: '#ff3200', // 阳线边框颜色 color0: '#00aa11' // 阴线边框颜色 } }, emphasis: { // color: 各异, // color0: 各异 } } }, // 散点图默认参数 scatter: { //symbol: null, // 图形类型 symbolSize: 4, // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize 2 //symbolRotate : null, // 图形旋转控制 large: false, // 大规模散点图 largeThreshold: 2000,// 大规模阀值,large为true且数据量>largeThreshold才启用大规模模式 itemStyle: { normal: { // color: 各异, label: { show: false // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } }, emphasis: { // color: '各异' label: { show: false // position: 默认自适应,水平布局为'top',垂直布局为'right',可选为 // 'inside'|'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } } }, // 雷达图默认参数 radar : { itemStyle: { normal: { // color: 各异, label: { show: false }, lineStyle: { width: 2, type: 'solid' } }, emphasis: { // color: 各异, label: { show: false } } }, //symbol: null, // 拐点图形类型 symbolSize: 2 // 可计算特性参数,空数据拖拽提示图形大小 //symbolRotate : null, // 图形旋转控制 }, // 饼图默认参数 pie: { center : ['50%', '50%'], // 默认全局居中 radius : [0, '75%'], clockWise : false, // 默认逆时针 startAngle: 90, minAngle: 0, // 最小角度改为0 selectedOffset: 10, // 选中是扇区偏移量 itemStyle: { normal: { // color: 各异, borderColor: '#fff', borderWidth: 1, label: { show: true, position: 'outer' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, labelLine: { show: true, length: 20, lineStyle: { // color: 各异, width: 1, type: 'solid' } } }, emphasis: { // color: 各异, borderColor: 'rgba(0,0,0,0)', borderWidth: 1, label: { show: false // position: 'outer' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, labelLine: { show: false, length: 20, lineStyle: { // color: 各异, width: 1, type: 'solid' } } } } }, map: { mapType: 'china', // 各省的mapType暂时都用中文 mapLocation: { x : 'center', y : 'center' // width // 自适应 // height // 自适应 }, showLegendSymbol : true, // 显示图例颜色标识(系列标识的小圆点),存在legend时生效 itemStyle: { normal: { // color: 各异, borderColor: '#fff', borderWidth: 1, areaStyle: { color: '#ccc'//rgba(135,206,250,0.8) }, label: { show: false, textStyle: { color: 'rgba(139,69,19,1)' } } }, emphasis: { // 也是选中样式 // color: 各异, borderColor: 'rgba(0,0,0,0)', borderWidth: 1, areaStyle: { color: 'rgba(255,215,0,0.8)' }, label: { show: false, textStyle: { color: 'rgba(139,69,19,1)' } } } } }, force : { // 数据map到圆的半径的最小值和最大值 minRadius : 10, maxRadius : 20, density : 1.0, attractiveness : 1.0, // 初始化的随机大小位置 initSize : 300, // 向心力因子,越大向心力越大 centripetal : 1, // 冷却因子 coolDown : 0.99, // 分类里如果有样式会覆盖节点默认样式 itemStyle: { normal: { // color: 各异, label: { show: false // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, nodeStyle : { brushType : 'both', color : '#f08c2e', strokeColor : '#5182ab' }, linkStyle : { strokeColor : '#5182ab' } }, emphasis: { // color: 各异, label: { show: false // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, nodeStyle : {}, linkStyle : {} } } }, chord : { radius : ['65%', '75%'], center : ['50%', '50%'], padding : 2, sort : 'none', // can be 'none', 'ascending', 'descending' sortSub : 'none', // can be 'none', 'ascending', 'descending' startAngle : 90, clockWise : false, showScale : false, showScaleText : false, itemStyle : { normal : { label : { show : true // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle : { width : 0, color : '#000' }, chordStyle : { lineStyle : { width : 1, color : '#666' } } }, emphasis : { lineStyle : { width : 0, color : '#000' }, chordStyle : { lineStyle : { width : 2, color : '#333' } } } } }, island: { r: 15, calculateStep: 0.1 // 滚轮可计算步长 0.1 = 10% }, markPoint : { symbol: 'pin', // 标注类型 symbolSize: 10, // 标注大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize 2 //symbolRotate : null, // 标注旋转控制 itemStyle: { normal: { // color: 各异, // borderColor: 各异, // 标注边线颜色,优先于color borderWidth: 2, // 标注边线线宽,单位px,默认为1 label: { show: true, position: 'inside' // 可选为'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } }, emphasis: { // color: 各异 label: { show: true // position: 'inside' // 'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE } } } }, markLine : { // 标线起始和结束的symbol介绍类型,如果都一样,可以直接传string symbol: ['circle', 'arrow'], // 标线起始和结束的symbol大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize 2 symbolSize: [2, 4], // 标线起始和结束的symbol旋转控制 //symbolRotate : null, itemStyle: { normal: { // color: 各异, // 标线主色,线色,symbol主色 // borderColor: 随color, // 标线symbol边框颜色,优先于color borderWidth: 2, // 标线symbol边框线宽,单位px,默认为2 label: { show: false, // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom' position: 'inside', textStyle: { // 默认使用全局文本样式,详见TEXTSTYLE color: '#333' } }, lineStyle: { // color: 随borderColor, // 主色,线色,优先级高于borderColor和color // width: 随borderWidth, // 优先于borderWidth type: 'solid', shadowColor : 'rgba(0,0,0,0)', //默认透明 shadowBlur: 5, shadowOffsetX: 3, shadowOffsetY: 3 } }, emphasis: { // color: 各异 label: { show: false // position: 'inside' // 'left'|'right'|'top'|'bottom' // textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE }, lineStyle : {} } } }, textStyle: { decoration: 'none', fontFamily: 'Arial, Verdana, sans-serif', fontFamily2: '微软雅黑', // IE8- 字体模糊并且不支持不同字体混排,额外指定一份 fontSize: 12, fontStyle: 'normal', fontWeight: 'normal' }, // 默认标志图形类型列表 symbolList : [ 'circle', 'rectangle', 'triangle', 'diamond', 'emptyCircle', 'emptyRectangle', 'emptyTriangle', 'emptyDiamond' ], loadingText : 'Loading...', // 可计算特性配置,孤岛,提示颜色 calculable: false, // 默认关闭可计算特性 calculableColor: 'rgba(255,165,0,0.6)', // 拖拽提示边框颜色 calculableHolderColor: '#ccc', // 可计算占位提示颜色 nameConnector: ' & ', valueConnector: ' : ', animation: true, animationThreshold: 2500, // 动画元素阀值,产生的图形原素超过2500不出动画 addDataAnimation: true, // 动态数据接口是否开启动画效果 animationDuration: 2000, animationEasing: 'ExponentialOut' //BounceOut}css修改滚动条默认样式

这是内容111

这里是内容222

这里是内容333

/滚动条样式/ .innerbox::-webkit-scrollbar {/滚动条整体样式/ width: 4px; /高宽分别对应横竖滚动条的尺寸/ height: 4px; } .innerbox::-webkit-scrollbar-thumb {/滚动条里面小方块/ border-radius: 5px; -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2); background: rgba(0,0,0,0.2); } .innerbox::-webkit-scrollbar-track {/滚动条里面轨道/ -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2); border-radius: 0; background: rgba(0,0,0,0.1); }js(=>) 箭头函数 详细解说 案例大全ES6标准新增了一种新的函数:Arrow Function(箭头函数)。为什么叫Arrow Function?因为它的定义用的就是一个箭头:x => x x上面的箭头函数相当于:function (x) { return x x;}箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }和return:复制代码x => { if (x > 0) { return x x; } else { return - x x; }}复制代码如果参数不是一个,就需要用括号()括起来:复制代码// 两个参数:(x, y) => x x + y y// 无参数:() => 3.14// 可变参数:(x, y, ...rest) => { var i, sum = x + y; for (i=0; i { foo: x }因为和函数体的{ ... }有语法冲突,所以要改为:// ok:x => ({ foo: x })this箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。回顾前面的例子,由于JavaScript函数对this绑定的错误处理,下面的例子无法得到预期结果:复制代码var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); }};复制代码现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj:复制代码var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象 return fn(); }};obj.getAge(); // 25复制代码如果使用箭头函数,以前的那种hack写法:var that = this;就不再需要了。由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:复制代码var obj = { birth: 1990, getAge: function (year) { var b = this.birth; // 1990 var fn = (y) => y - this.birth; // this.birth仍是1990 return fn.call({birth:2000}, year); }};obj.getAge(2015); // 25使用 let 语句声明一个变量,该变量的范围限于声明它的块中。 可以在声明变量时为变量赋值,也可以稍后在脚本中给变量赋值。 使用 let 声明的变量,在声明前无法使用,否则将会导致错误。如果未在 let 语句中初始化您的变量,则将自动为其分配 JavaScript 值 undefined逗号,空格,冒号,点号的含义 一:#a,b{…………} 二:#a b{…………} 三:#a:b{…………} 四:#a.b{…………}一、一个id叫a和一个标签是b的样式二、一个id叫a下面的一个标签是b的样式三、一个id叫a的伪类b的样式四、一个id叫a的下面的class叫b的样式overflow(超出部分省略号)溢出:overflow:visible/hidden/scroll/auto/inherit;visible:默认值、不剪切。hidden:超出部分剪切、没有滚动条。scroll:超出部分有滚动条。auto:自适应,有滚动条。inherit:继承父元素的overflow得值。空余空间:white-space:pre/pre-wrap/nowrap/pre-line/inherit;pre:识别回车和空格、不换行。pre-wrap:识别回车和空格、换行。nowrap:不识别回车和空格、不换行。pre-line:识别回车、不识别空格、识别换行。inherit:继承父元素的white-space属性。实例:(1)单行实现省略号:width:valve;white-space:nowrap;overflow:hidden;text-overflow:ellipse;(2)可以不要设置高 自适应 别忘了overflow:hidden;复制代码.box{  width: 100%;// height: .70rem;// line-height: .36rem;  margin: .2rem 0 .4rem;  font-size: .28rem;  overflow: hidden;}复制代码//超出部分隐藏(可设置多行之后省略号)复制代码//两行超出隐藏.overhide {  display: -webkit-box !important;  text-overflow: ellipsis;  overflow: hidden;  -webkit-line-clamp: 2;  -webkit-box-orient: vertical;}//一行超出隐藏.overhideline1 {  display: -webkit-box !important;  text-overflow: ellipsis;  overflow: hidden;  -webkit-line-clamp: 1;  -webkit-box-orient: vertical;}[eslint-plugin-vue][vue/require-v-for-key]Elements in iteration expect to have 'v-bind:key' directives.这是因为我们安装了ESLint插件,对vue进行了eslint检查,只需将这个规则检查屏蔽掉即可,具体操作如下: 文件–》首选项–》设置–》在搜索框中输入:vetur.validation.template–》找到vetur.validation.template:true–》将vetur.validation.template:true在右栏框中进行重置为false就ok了。 用CSS让文字在一行内显示不换行的方法一般的文字截断(适用于内联与块):.text-overflow{display:block; /内联对象需加/width:31em;word-break:keep-all; / 不换行 /white-space:nowrap; / 不换行 /overflow:hidden; / 内容超出宽度时隐藏超出部分的内容 /text-overflow:ellipsis; / 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。/}对于表格,定义有点不一样:table{width:30em;table-layout:fixed; / 只有定义了表格的布局算法为fixed,下面td的定义才能起作用。 /}td{width:100%;word-break:keep-all; / 不换行 /white-space:nowrap; / 不换行 /overflow:hidden; / 内容超出宽度时隐藏超出部分的内容 /text-overflow:ellipsis; / 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。/}注:这个只对单行的文字的效,如果你想把它用在多行上,也只有第一行有作用的。 这个写法只有IE会有“...”,其它的浏览器文本超出指定宽度时会隐藏。

$_SERVER中HTTP_HOST和SERVER_NAME的区别

相同点:
当满足以下三个条件时,两者会输出相同信息。
1. 服务器为80端口
2. apache的conf中ServerName设置正确
3. HTTP/1.1协议规范
不同点:
1. 通常情况:
_SERVER["HTTP_HOST"] 在HTTP/1.1协议规范下,会根据客户端的HTTP请求输出信息。
_SERVER["SERVER_NAME"] 默认情况下直接输出apache的配置文件httpd.conf中的ServerName值。
2. 当服务器为非80端口时:
_SERVER["HTTP_HOST"] 会输出端口号,例如:xxxxx.cn:8080
_SERVER["SERVER_NAME"] 会直接输出ServerName值
因此在这种情况下,可以理解为:HTTP_HOST = SERVER_NAME : SERVER_PORT
3. 当配置文件httpd.conf中的ServerName与HTTP/1.0请求的域名不一致时:
httpd.conf配置如下:
ServerName xxxxx.cn
ServerAlias www.xxxxx.cn
客户端访问域名www.xxxxx.cn
_SERVER["HTTP_HOST"] 输出 www.xxxxx.cn
_SERVER["SERVER_NAME"] 输出 xxxxx.cn
在实际程序中,使用_SERVER["HTTP_HOST"]比较可靠

$_SERVER变量详解

$_SERVER["QUERY_STRING"],
$_SERVER["REQUEST_URI"],
$_SERVER["SCRIPT_NAME"],
$_SERVER["PHP_SELF"]
实例详解$_SERVER函数中QUERY_STRING,REQUEST_URI,SCRIPT_NAME和PHP_SELF变量区别,掌握这四者之间的关系,便于在实际应用中正确获取所需要的值,供参考。
1,$_SERVER["QUERY_STRING"]
说明:查询(query)的字符串
2,$_SERVER["REQUEST_URI"]
说明:访问此页面所需的URI
3,$_SERVER["SCRIPT_NAME"]
说明:包含当前脚本的路径
4,$_SERVER["PHP_SELF"]
说明:当前正在执行脚本的文件名
实例:
1,http://ask.mbatrip.com (打开主页)
结果:
$_SERVER["QUERY_STRING"] = “”
$_SERVER["REQUEST_URI"] = “/”
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”
2,http://ask.mbatrip.com/?tags/上传(附带查询)
结果:
$_SERVER["QUERY_STRING"] = “tags/上传″
$_SERVER["REQUEST_URI"] = “/?tags/上传″
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”
3,http://ask.mbatrip.com/?tags/上传/2
结果:
$_SERVER["QUERY_STRING"] = “tags/上传/2”
$_SERVER["REQUEST_URI"] = “/index.php?tags/上传/2”
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”
$_SERVER["QUERY_STRING"]获取查询语句,实例中可知,获取的是?后面的值
$_SERVER["REQUEST_URI"] 获取http://ask.mbatrip.com后面的值,包括/
$_SERVER["SCRIPT_NAME"] 获取当前脚本的路径,如:index.php
$_SERVER["PHP_SELF"] 当前正在执行脚本的文件名
function checkurl(){
if(!isset($_SESSION['HTTP_REFERER'])) {
header("location: login");
exit;
}
$urlar = parse_url($_SESSION['HTTP_REFERER']);
if($_SERVER['HTTP_HOST'] != $urlar["host"] && $urlar["host"] != "202.102.110.204" && $urlar["host"] != "http://blog.163.com/fantasy_lxh/") {
header("location: login.php");
exit;
}
}
checkurl()

跨域问题

不同域名是无法共享浏览器端本地信息,包括cookies,无法跨域问题,SSO单点登录可以提供解决方案,下面是SSO单点登录的技术实现机制:
1、需要一个统一处理用户登录的单点系统UserCenter。该系统集中处理用户信息,包括用户信息加密存储,用户注册,用户登录验证,SSO接入等;
2、需要接入SSO单点登录的系统(例如业务系统A)不处理任何用户登录信息,服务器端在用户第一次提交请求时,跳转到SSO系统验证是否登陆,如未登录,则一般重定向SSO系统的登录页面,用户登录成功以后,再回跳到业务系统A原来的页面,业务系统A与此同时写入由SSO带回来的用户信息到session中,后续的交互过程中,业务系统A就一直保持有用户的登录信息了。
3、假如用户由上述登录过的业务系统A跳转访问到同样接入到SSO单点登录系统UserCenter的业务系统B,此时业务系统B没有用户登录信息,同样会跳转SSO单点登录系统验证是否登录,SSO检测到用户之前已登录,又重定向到业务系统B,此时系统B从SSO带回登录信息并写入到session,这样用户就做到了,一处登录多处保持登录信息,即完成了SSO单点登录。
需要特别说明的是:在这个SSO单点登录过程中,上述SSO系统UserCenter、业务系统A和业务系统B都会在客户端写入标志登录状态的cookies,其中有且仅有SSO系统保存有用户密码等私密信息,业务系统A和B仅只可访问到用户标识信息,这样也很好地保证了用户信息的安全性。
PS:在移动互联网大行其道的今天,SSO提供多种登录验证方式也很重要,除了传统的HTTP、API接入,现在也会提供手机动态验证码、手机二维码、硬件密码令牌等多种新型登录验证方式。
AJAX 跨域请求 - JSONP获取JSON数据
Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术。Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。
不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数 据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办?
理解同源策略限制
同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。
克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。
克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。
1、什么是JSONP?
要了解JSONP,不得不提一下JSON,那么什么是JSON ?
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
2、JSONP有什么用?
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
3、如何使用JSONP?
下边这一DEMO实际上是JSONP的简单表现形式,在客户端声明回调函数之后,客户端通过script标签向服务器跨域请求数据,然后服务端返回相应的数据并动态执行回调函数。
HTML代码:
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
function jsonpCallback(result) {
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
}
var JSONP=document.createElement("script");
JSONP.type="text/javascript";
JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";
document.getElementsByTagName("head")[0].appendChild(JSONP);
</script>
或者
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
function jsonpCallback(result) {
alert(result.a);
alert(result.b);
alert(result.c);
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
}
</script>
<script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script>
JavaScript的链接,必须在function的下面。
服务端PHP代码 (services.php):
<?php
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
$result=json_encode($arr);
$callback=$_GET['callback'];
echo $callback."($result)";
如果将上述JS客户端代码用jQuery的方法来实现,也非常简单。
$.getJSON
$.ajax
$.get
客户端JS代码在jQuery中的实现方式1:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$.getJSON("http://crossdomain.com/services.php?callback=?",
function(result) {
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
});
</script>
客户端JS代码在jQuery中的实现方式2:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$.ajax({
url:"http://crossdomain.com/services.php",
dataType:'jsonp',
data:'',
jsonp:'callback',
success:function(result) {
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
},
timeout:3000
});
</script>
客户端JS代码在jQuery中的实现方式3:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$.get('http://crossdomain.com/services.php?callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+":"+json[i]); }, 'jsonp');
</script>
其中 jsonCallback 是客户端注册的,获取 跨域服务器 上的json数据 后,回调的函数。
http://crossdomain.com/services.php?callback=jsonpCallback
这个 url 是跨域服务 器取 json 数据的接口,参数为回调函数的名字,返回的格式为
jsonpCallback({msg:'this is json data'})
Jsonp原理:
首先在客户端注册一个callback, 然后把callback的名字传给服务器。
此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
使用JSON的优点在于:
比XML轻了很多,没有那么多冗余的东西。
JSON也是具有很好的可读性的,但是通常返回的都是压缩过后的。不像XML这样的浏览器可以直接显示,浏览器对于JSON的格式化的显示就需要借助一些插件了。
在JavaScript中处理JSON很简单。
其他语言例如PHP对于JSON的支持也不错。
JSON也有一些劣势:
JSON在服务端语言的支持不像XML那么广泛,不过JSON.org上提供很多语言的库。
如果你使用eval()来解析的话,会容易出现安全问题。
尽管如此,JSON的优点还是很明显的。他是Ajax数据交互的很理想的数据格式。
主要提示:
JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。
第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。(未来的 jQuery 版本可能有终止 JSONP 请求的特性)。
JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要。
SSO单点登录的实现原理是怎样的
单点登录在现在的系统架构中广泛存在,他将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登录实现方案来满足需求。我将以我所遇到的应用环境以及在其中所经历的各个阶段与大家分享,若有不足,希望各位不吝赐教。
当用户第一次访问系统1的时候,因为还没有登录,会被引导到认证系统中进行登录,根据用户提供的登录信息,认证系统进行身份检验,如果通过检验,就会返回给用户一个凭据--ticket;然而当用户访问别的应用的时候,就会讲ticket带上,作为自己的认证凭据,应用系统接收到这个应用凭据之后会把ticket送到认证系统中进行检验,检查ticket的合法性。如果通过校验,那么用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了;
一、共享Session
共享Session可谓是实现单点登录最直接、最简单的方式。将用户认证信息保存于Session中,即以Session内存储的值为用户凭证,这在单个站点内使用是很正常也很容易实现的,而在用户验证、用户信息管理与业务应用分离的场景下即会遇到单点登录的问题,在应用体系简单,子系统很少的情况下,可以考虑采用Session共享的方法来处理这个问题。
这个架构我使用了基于Redis的Session共享方案。将Session存储于Redis上,然后将整个系统的全局Cookie Domain设置于顶级域名上,这样SessionID就能在各个子系统间共享。
这个方案存在着严重的扩展性问题,首先,ASP.NET的Session存储必须为SessionStateItemCollection对象,而存储的结构是经过序列化后经过加密存储的。并且当用户访问应用时,他首先做的就是将存储容器里的所有内容全部取出,并且反序列化为SessionStateItemCollection对象。这就决定了他具有以下约束:
1、 Session中所涉及的类型必须是子系统中共同拥有的(即程序集、类型都需要一致),这导致Session的使用受到诸多限制;
2、 跨顶级域名的情况完全无法处理;
二、基于OpenId的单点登录
这种单点登录将用户的身份标识信息简化为OpenId存放于客户端,当用户登录某个子系统时,将OpenId传送到服务端,服务端根据OpenId构造用户验证信息,多用于C/S与B/S相结合的系统,流程如下:
可以看到,这套单点登录依赖于OpenId的传递,其验证的基础在于OpenId的存储以及发送。
   1、当用户第一次登录时,将用户名密码发送给验证服务;
   2、验证服务将用户标识OpenId返回到客户端;
   3、客户端进行存储;
   4、访问子系统时,将OpenId发送到子系统;
   5、子系统将OpenId转发到验证服务;
   6、验证服务将用户认证信息返回给子系统;
   7、子系统构建用户验证信息后将授权后的内容返回给客户端。
这套单点登录验证机制的主要问题在于他基于C/S架构下将用户的OpenId存储于客户端,在子系统之间发送OpenId,而B/S模式下要做到这一点就显得较为困难。为了处理这个问题我们将引出下一种方式,这种方式将解决B/S模式下的OpenId的存储、传递问题。
三、基于Cookie的OpenId存储方案
我们知道,Cookie的作用在于充当一个信息载体在Server端和Browser端进行信息传递,而Cookie一般是以域名为分割的,例如a.xxx.com与b.xxx.com的Cookie是不能互相访问的,但是子域名是可以访问上级域名的Cookie的。即a.xxx.com和b.xxx.com是可以访问xxx.com下的Cookie的,于是就能将顶级域名的Cookie作为OpenId的载体。
验证步骤:
  1、 在提供验证服务的站点里登录;
  2、 将OpenId写入顶级域名Cookie里;
  3、 访问子系统(Cookie里带有OpenId)
  4、 子系统取出OpenId通过并向验证服务发送OpenId
  5、 返回用户认证信息
  6、 返回授权后的内容
在以上两种方法中我们都可以看到通过OpenId解耦了Session共享方案中的类型等问题,并且构造用户验证信息将更灵活,子系统间的验证是相互独立的,但是在第三种方案里,我们基于所有子系统都是同一个顶级域名的假设,而在实际生产环境里有多个域名是很正常的事情,那么就不得不考虑跨域问题究竟如何解决。
四、B/S多域名环境下的单点登录处理
在多个顶级域名的情况下,我们将无法让各个子系统的OpenId共享。处理B/S环境下的跨域问题,我们首先就应该想到JSONP的方案。
步骤如下:
  1、 用户通过登录子系统进行用户登录;
  2、 用户登录子系统记录了用户的登录状态、OpenId等信息;
  3、 用户使用业务子系统;
  4、 若用户未登录业务子系统则将用户跳转至用户登录子系统;
  5、 用户子系统通过JSONP接口将用户OpenId传给业务子系统;
  6、 业务子系统通过OpenId调用验证服务;
  7、 验证服务返回认证信息、业务子系统构造用户登录凭证;(此时用户客户端已经与子业务系统的验证信息已经一一对应)
  8、 将用户登录结果返回用户登录子系统,若成功登录则将用户跳转回业务子系统;
  9、 将授权后的内容返回客户端;
五、安全问题
经过以上步骤,跨域情况下的单点登录问题已经可以得到解决。而在整个开发过程初期,我们采用用户表中纪录一个OpenId字段来保存用户OpenId,而这个机制下很明显存在一些安全性、扩展性问题。这个扩展性问题主要体现在一个方面:OpenId的安全性和用户体验的矛盾。
整个单点登录的机制决定了OpenId是会出现在客户端的,所以OpenId需要有过期机制,假如用户在一个终端登录的话可以选择在用户每次登录或者每次退出时刷新OpenId,而在多终端登录的情况下就会出现矛盾:当一个终端刷新了OpenId之后其他终端将无法正常授权。而最终,我采用了单用户多OpenId的解决方案。每次用户通过用户名/密码登录时,产生一个OpenId保存在Redis里,并且设定过期时间,这样多个终端登录就会有多个OpenId与之对应,不再会存在一个OpenId失效所有终端验证都失效的情况。

虚拟主机服务器php fsockopen函数被禁用的解决办法

一、如何禁用fsockopen()
下面是两种常用的禁用fsockopen的方法。
1、修改php.ini,将 disable_functions = 后加入 fsockopen
2、修改php.ini,将 allow_url_fopen = On 改为 allow_url_fopen = Off
二、如何解决fsockopen函数被禁用
1、如果服务器没有同时禁用pfsockopen,那么直接将fsockopen函数替换为pfsockopen。
具体操作:搜索程序中的字符串 fsockopen( 替换为 pfsockopen( 。示例如下
修改前:
$fp = fsockopen($host, 80, $errno, $errstr, 30);
修改后:
$fp = pfsockopen($host, 80, $errno, $errstr, 30);
2、如果服务器同时禁用了pfsockopen,那么用其他函数代替,如stream_socket_client()。注意:stream_socket_client()和fsockopen()的参数不同。
具体操作:搜索程序中的字符串 fsockopen( 替换为 stream_socket_client( ,然后,将原fsockopen函数中的端口参数“80”删掉,并加到$host。示例如下
修改前:
$fp = fsockopen($host, 80, $errno, $errstr, 30);
修改后
$fp = stream_socket_client($host."80", $errno, $errstr, 30);
3、如果PHP版本低于5.0,fsockopen被禁用,又没有stream_socket_client()怎么办呢?自己写一个函数实现fsockopen的功能,参考代码:
function b_fsockopen($host, $port, &$errno, &$errstr, $timeout) {
$ip = gethostbyname($host);
$s = socket_create(AF_INET, SOCK_STREAM, 0);
if (socket_set_nonblock($s)) {
$r = @socket_connect($s, $ip, $port);
if ($r || socket_last_error() == EINPROGRESS) {
$errno = EINPROGRESS;
return $s;
}
}
$errno = socket_last_error($s);
$errstr = socket_strerror($errno);
socket_close($s);
return false;
}
具体操作:1.首先找到使用fsockopen函数的代码段,将上面代码加至其上端,搜索该代码段中的字符串 fsockopen( 替换为 b_fsockopen( 。
2.因为fsockopen函数返回文件指针所以可以被文件函数操作,但是这个b_fsockopen函数没能返回文件指针,需要继续修改代码段:用socket_read( 替换掉 fread( ,用socket_write( 替换掉fwrite( ,用socket_close( 替换掉fclose( 。

fsockopen get/post

$fp = fsockopen("www.happylivelife.com", 80, $errno, $errstr, 30);
echo 'xxxx:'.$fp .'<br>';
$out = "get / http/1.1 ";
$out .= "host: www.happylivelife.com";
$out .= "connection: close ";
fwrite($fp, $out);
while (!feof($fp))
{
echo fgets($fp, 1024);
}
fclose($fp);

下载链接

$filename = '/path/'.$_GET['file'].'.txt'; //文件路径
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=".basename($filename));
readfile($filename);

JavaScript 判断网站是否可以打开

iframe
if (!document.getElementById("TEST").document.getElementsByTagName("body"))
{
alert("抱歉,你无法访问XX网站");
}
img src="另一网站的某个图片URL" onerror="warning()" /
function warning()
{
alert("无法访问XX站");
}

Please complete the security check to access解决

原因:
服务器访问过大时,会要求访问者输入验证码以便继续访问。
解决:
可以输入验证码以便继续,或者等以后再试

1. JavaScript常用方法

(1) Location 对象详解

Location 对象包含有关当前 URL 的信息,是 Window 对象的一个部分,可通过 window.location 属性来访问。
1) Location 对象属性
hash 设置或返回从井号 (#) 开始的 URL(锚)。
host 设置或返回主机名和当前 URL 的端口号。
hostname 设置或返回当前 URL 的主机名。
href 设置或返回完整的 URL。
pathname 设置或返回当前 URL 的路径部分。
port 设置或返回当前 URL 的端口号。
protocol 设置或返回当前 URL 的协议。
search 设置或返回从问号 (?) 开始的 URL(查询部分)。
2) Location 对象方法
assign() 加载新的文档。
reload() 重新加载当前文档。
replace() 用新的文档替换当前文档。
3) Location 对象描述
Location 对象存储在 Window 对象的 Location 属性中,表示那个窗口中当前显示的文档的 Web 地址。它的 href 属性存放的是文档的完整 URL,其他属性则分别描述了 URL 的各个部分。这些属性与 Anchor 对象(或 Area 对象)的 URL 属性非常相似。当一个 Location 对象被转换成字符串,href 属性的值被返回。这意味着你可以使用表达式 location 来替代 location.href。
不过 Anchor 对象表示的是文档中的超链接,Location 对象表示的却是浏览器当前显示的文档的 URL(或位置)。但是 Location 对象所能做的远远不止这些,它还能控制浏览器显示的文档的位置。如果把一个含有 URL 的字符串赋予 Location 对象或它的 href 属性,浏览器就会把新的 URL 所指的文档装载进来,并显示出来。
除了设置 location 或 location.href 用完整的 URL 替换当前的 URL 之外,还可以修改部分 URL,只需要给 Location 对象的其他属性赋值即可。这样做就会创建新的 URL,其中的一部分与原来的 URL 不同,浏览器会将它装载并显示出来。例如,假设设置了Location对象的 hash 属性,那么浏览器就会转移到当前文档中的一个指定的位置。同样,如果设置了 search 属性,那么浏览器就会重新装载附加了新的查询字符串的 URL。
除了 URL 属性外,Location 对象的 reload() 方法可以重新装载当前文档,replace() 可以装载一个新文档而无须为它创建一个新的历史记录,也就是说,在浏览器的历史列表中,新文档将替换当前文档。
网页加载方法区别详解
(1) 刷新
reload 方法,该方法强迫浏览器刷新当前页面。
语法: location.reload([bForceGet])
参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页。true, 则以 GET 方式,从服务端取最新的页面, 相当于客户端点击 F5("刷新")
replace 方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后退”来访问已经被替换的URL。
语法: location.replace(URL)
在实际应用的时候,重新刷新页面的时候,我们通常使用: location.reload() 或者是 history.go(0) 来做。
因为这种做法就像是客户端点F5刷新页面,所以页面的method="post"的时候,会出现“网页过期”的提示。那是因为Session的安全保护机制。当调用 location.reload() 方法的时候, aspx页面此时在服务端内存里已经存在, 因此必定是 IsPostback 的。
如果有这种应用: 我们需要重新加载该页面,也就是说我们期望页面能够在服务端重新被创建, 我们期望是 Not IsPostback 的。这里,location.replace() 就可以完成此任务。被replace的页面每次都在服务端重新生成。你可以这么写: location.replace(location.href)
(2) 重定向
window.location.href
window.top.location.replace("http://www.happylivelife.com/")
top.location.href("http://www.happylivelife.com/")
window.navigate ("http://www.happylivelife.com/")
Html:
<meta http-equiv="Refresh" content="0; url=http://www.happylivelife.com/" >
---------------------------------------
(1)(2)的不同之处是,(2)会在浏览器的历史浏览记录(history对象)中增加一条新的记录
URL详解
统一资源定位符 (Uniform Resource Locator, URL)
完整的URL由这几个部分构成:
scheme://host:port/path?query#fragment
scheme:通信协议
常用的http,ftp,maito等
host:主机
服务器(计算机)域名系统 (DNS) 主机名或 IP 地址。
port:端口号
整数,可选,省略时使用方案的默认端口,如http的默认端口为80。
path:路径
由零或多个"/"符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。
query:查询
可选,用于给动态网页(如使用CGI、ISAPI、PHP/JSP/ASP/ASP.NET等技术制作的网页)传递参数,可有多个参数,用"&"符号隔开,每个参数的名和值用"="符号隔开。
fragment:信息片断
字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释。(也称为锚点.)
对于这样一个URL
http://www.happylivelife.com/fisker/post/0703/window.location.html?ver=1.0&id=6#imhere
我们可以用javascript获得其中的各个部分
1, window.location.href
整个URl字符串(在浏览器中就是完整的地址栏)
本例返回值: http://www.happylivelife.com/fisker/post/0703/window.location.html?ver=1.0&id=6#imhere
2,window.location.protocol
URL 的协议部分
本例返回值:http:
3,window.location.host
URL 的主机部分
本例返回值:www.jb51.net
4,window.location.port
URL 的端口部分
如果采用默认的80端口(update:即使添加了:80),那么返回值并不是默认的80而是空字符
本例返回值:""
5,window.location.pathname
URL 的路径部分(就是文件地址)
本例返回值:/fisker/post/0703/window.location.html
6,window.location.search
查询(参数)部分
除了给动态语言赋值以外,我们同样可以给静态页面,并使用javascript来获得相信应的参数值
本例返回值:?ver=1.0&id=6
7,window.location.hash
锚点
本例返回值:#imhere

2. PHP 详解

(1) $_SERVER详解

详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别
实例:
1,http://localhost/aaa/
结果:
$_SERVER['QUERY_STRING'] = "";
$_SERVER['REQUEST_URI'] = "/aaa/";
$_SERVER['SCRIPT_NAME'] = "/aaa/index.php";
$_SERVER['PHP_SELF'] = "/aaa/index.php";
2,http://localhost/aaa/?p=222
结果:
$_SERVER['QUERY_STRING'] = "p=222";
$_SERVER['REQUEST_URI'] = "/aaa/?p=222";
$_SERVER['SCRIPT_NAME'] = "/aaa/index.php";
$_SERVER['PHP_SELF'] = "/aaa/index.php";
3,http://localhost/aaa/index.php?p=222&q=333
结果:
$_SERVER['QUERY_STRING'] = "p=222&q=333";
$_SERVER['REQUEST_URI'] = "/aaa/index.php?p=222&q=333";
$_SERVER['SCRIPT_NAME'] = "/aaa/index.php";
$_SERVER['PHP_SELF'] = "/aaa/index.php";
由实例可知:
$_SERVER["QUERY_STRING"] 获取查询 语句,实例中可知,获取的是?后面的值
$_SERVER["REQUEST_URI"] 获取 http://localhost 后面的值,包括/
$_SERVER["SCRIPT_NAME"] 获取当前脚本的路径,如:index.php
$_SERVER["PHP_SELF"] 当前正在执行脚本的文件名
在PHP中require,include一个文件时,相对路径容易出错。
例如:
<web>(网站根目录)
├<A>文件夹
│ │
│ └1.php
├<B>文件夹
│ │
│ └2.php
└index.php
问题:在1.php中通过include(“../B/2.php”)来引入B目录下的2.php文件;
在index.php中通过include(“A/1.php”)来引入A目录下的1.php文件;
运行出来当然会出现问题,找不到../B/2.php文件。
这是因为:
1.php被编译到index.php中执行,也就是相当于1.php同index.php一样位于网站根目录下,但是在1.php别忘记了一断代码include(“../B/2.php”);
“../”意味着什么?上一级目录,现在1.php已经在根目录下了,这时候再上一级,那就已经找不到2.php了,所以问题就出现在此。
很多人会想到include(“/B/2.php”),这样不就好了,同样不行php不同于我们的jsp,在include中使用”/”并不是我们所想象的网站根目录,它代表的的
当前的目录,因此还是不行。
既然不能用相对的,那我们可以改用绝对路径的方式。只是在包含文件之前,先包含一个global.php
文件。这个文件的内容是:
<?php
chdir(dirname(__FILE__));
?>
,它的作用是将当前目录切换到global.php所在的路径。
将global.php放在根目时录下,在这之后包含的所有文件就会以根目录为基准了。
例如,在2.php中引用1.php,则,通过2步:
1.require(dirname(__FILE__).‘/../global.php’);//视具体的目录情况,反正是要指回到根目录下的global.php
2.require(‘A/1.php’)//从根目录开始定位
这样的话,不管页面在哪一级目录,我都可以去引用,不用再担心路径问题了!

3. HTML 标签详解

(1) base 标签
<base> 标签为页面上的所有链接规定默认地址或默认目标。
通常情况下,浏览器会从当前文档的 URL 中提取相应的元素来填写相对 URL 中的空白。
使用 <base> 标签可以改变这一点。浏览器随后将不再使用当前文档的 URL,而使用指定的基本 URL 来解析所有的相对 URL。这其中包括 <a>、<img>、<link>、<form> 标签中的 URL。
如不起作用,是可能是之前有输出,去掉即可生效。

4. 使用OpenSearch description documents自定义您的搜索引擎并添加到IE浏览器中

如果您的网站提供了搜索引擎类的功能,又希望您网站的搜索引擎入口添加到IE浏览器加载项中,可按以下步骤操作:
步骤一:定义OSD文件,存为HappySearch.xml,参考如下:
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>快乐搜过</ShortName>
<Description>正则搜索</Description>
<Tags>快乐 正则 搜索</Tags>
<Contact>service@happylivelife.com</Contact>
<Url type="text/html" template="http://www.happylivelife.com/hs?hd={searchTerms}&p={startPage?}"/>
</OpenSearchDescription>
步骤二:在微软上注册帐号,如果已有帐号跳过此步骤
打开https://login.live.com/网址进行帐号注册
步骤三:将您的搜索引擎提交到库,方法:
(1)打开网址:http://www.iegallery.com/Account/Resources
用您在微软上注册的帐号登录
(2)选择“开发人员和合作伙伴” -> "加载项" -> "加载项上传"
http://www.iegallery.com/AddOns/Edit
(3)按里面的要求填写搜索引擎资料,在“提交类型”一栏选择“搜索提供商”,上传OSD定义文件,添加您自己的搜索引擎
然后等待审核。
步骤四:把上面存的HappySearch.xml文件上传到您的网站上,并在您的搜索引擎网页里面的<head>和</head>加入
将代码中的相文信息改成您的信息,这步的用主要是让浏览器自动识别此搜索引擎,这此完成后,用带搜索框的IE、火狐浏览器访问您的搜索引擎网站,在搜索框下拉框就可以看到自定义的搜索引擎了。

Robots

Robots协议用来告知搜索引擎哪些页面能被抓取,哪些页面不能被抓取;可以屏蔽一些网站中比较大的文件,如:图片,音乐,视频等,节省服务器带宽;可以屏蔽站点的一些死链接。方便搜索引擎抓取网站内容;设置网站地图连接,方便引导蜘蛛爬取页面。
文件写法
User-agent: * 这里的*代表的所有的搜索引擎种类,*是一个通配符
Disallow: /admin/ 这里定义是禁止爬寻admin目录下面的目录
Disallow: /require/ 这里定义是禁止爬寻require目录下面的目录
Disallow: /ABC/ 这里定义是禁止爬寻ABC目录下面的目录
Disallow: /cgi-bin/*.htm 禁止访问/cgi-bin/目录下的所有以".htm"为后缀的URL(包含子目录)。
Disallow: /*?* 禁止访问网站中所有包含问号 (?) 的网址
Disallow: /.jpg$ 禁止抓取网页所有的.jpg格式的图片
Disallow:/ab/adc.html 禁止爬取ab文件夹下面的adc.html文件。
Allow: /cgi-bin/ 这里定义是允许爬寻cgi-bin目录下面的目录
Allow: /tmp 这里定义是允许爬寻tmp的整个目录
Allow: .htm$ 仅允许访问以".htm"为后缀的URL。
Allow: .gif$ 允许抓取网页和gif格式图片
Sitemap: 网站地图 告诉爬虫这个页面是网站地图
文件用法
例1. 禁止所有搜索引擎访问网站的任何部分
User-agent: *
Disallow: /
实例分析:淘宝网的 Robots.txt文件
User-agent: Baiduspider
Disallow: /
User-agent: baiduspider
Disallow: /
很显然淘宝不允许百度的机器人访问其网站下其所有的目录。
例2. 允许所有的robot访问 (或者也可以建一个空文件 “/robots.txt” file)
User-agent: *
Allow: /
例3. 禁止某个搜索引擎的访问
User-agent: BadBot
Disallow: /
例4. 允许某个搜索引擎的访问
User-agent: Baiduspider
allow:/
例5.一个简单例子
在这个例子中,该网站有三个目录对搜索引擎的访问做了限制,即搜索引擎不会访问这三个目录。
需要注意的是对每一个目录必须分开声明,而不要写成 “Disallow: /cgi-bin/ /tmp/”。
User-agent:后的*具有特殊的含义,代表“any robot”,所以在该文件中不能有“Disallow: /tmp/*” or “Disallow:*.gif”这样的记录出现。
User-agent: *
Disallow: /cgi-bin/
Disallow: /tmp/
Disallow: /~joe/
Robot特殊参数:
允许 Googlebot:
如果您要拦截除Googlebot以外的所有漫游器不能访问您的网页,可以使用下列语法:
User-agent:
Disallow: /
User-agent: Googlebot
Disallow:
Googlebot 跟随指向它自己的行,而不是指向所有漫游器的行。
“Allow”扩展名:
Googlebot 可识别称为“Allow”的 robots.txt 标准扩展名。其他搜索引擎的漫游器可能无法识别此扩展名,因此请使用您感兴趣的其他搜索引擎进行查找。“Allow”行的作用原理完全与“Disallow”行一样。只需列出您要允许的目录或页面即可。
您也可以同时使用“Disallow”和“Allow”。例如,要拦截子目录中某个页面之外的其他所有页面,可以使用下列条目:
User-agent: Googlebot
Allow: /folder1/myfile.html
Disallow: /folder1/
这些条目将拦截 folder1 目录内除 myfile.html 之外的所有页面。
如果您要拦截 Googlebot 并允许 Google 的另一个漫游器(如 Googlebot-Mobile),可使用”Allow”规则允许该漫游器的访问。例如:
User-agent: Googlebot
Disallow: /
User-agent: Googlebot-Mobile
Allow:
使用 * 号匹配字符序列:
您可使用星号 (*) 来匹配字符序列。例如,要拦截对所有以 private 开头的子目录的访问,可使用下列条目: User-Agent: Googlebot
Disallow: /private*/
要拦截对所有包含问号 (?) 的网址的访问,可使用下列条目:
User-agent: *
Disallow: /*?*
使用 $ 匹配网址的结束字符
您可使用 $字符指定与网址的结束字符进行匹配。例如,要拦截以 .asp 结尾的网址,可使用下列条目: User-agent: Googlebot
Disallow: /*.asp$
您可将此模式匹配与 Allow 指令配合使用。例如,如果 ? 表示一个会话 ID,您可排除所有包含该 ID 的网址,确保 Googlebot 不会抓取重复的网页。但是,以 ? 结尾的网址可能是您要包含的网页版本。在此情况下,可对 robots.txt 文件进行如下设置:
User-agent: *
Allow: /*?$
Disallow: /*?
Disallow: / *?
一行将拦截包含 ? 的网址(具体而言,它将拦截所有以您的域名开头、后接任意字符串,然后是问号 (?),而后又是任意字符串的网址)。
Allow: /*?$ 一行将允许包含任何以 ? 结尾的网址(具体而言,它将允许包含所有以您的域名开头、后接任意字符串,然后是问号 (?),问号之后没有任何字符的网址)。
尽管robots.txt已经存在很多年了,但是各大搜索引擎对它的解读都有细微差别。Google与百度都分别在自己的站长工具中提供了robots工具。如果您编写了robots.txt文件,建议您在这两个工具中都进行测试,因为这两者的解析实现确实有细微差别[1] 。
其它属性
1. Robot-version: 用来指定robot协议的版本号
例子: Robot-version: Version 2.0
2.Crawl-delay:雅虎YST一个特定的扩展名,可以通过它对我们的抓取程序设定一个较低的抓取请求频率。您可以加入Crawl-delay:xx指示,其中,“XX”是指在crawler程序两次进入站点时,以秒为单位的最低延时。
3. Visit-time:只有在visit-time指定的时间段里,robot才可以访问指定的URL,否则不可访问.
例子: Visit-time: 0100-1300 #允许在凌晨1:00到13:00访问
4. Request-rate: 用来限制URL的读取频率
例子: Request-rate: 40/1m 0100 - 0759 在1:00到07:59之间,以每分钟40次的频率进行访问
Request-rate: 12/1m 0800 - 1300 在8:00到13:00之间,以每分钟12次的频率进行访问
标签
Robots.txt文件主要是限制整个站点或者目录的搜索引擎访问情况,而Robots Meta标签则主要是针对一个个具体的页面。和其他的META标签(如使用的语言、页面的描述、关键词等)一样,Robots Meta标签也是放在页面中,专门用来告诉搜索引擎ROBOTS如何抓取该页的内容。
Robots Meta标签中没有大小写之分,name=”Robots”表示所有的搜索引擎,可以针对某个具体搜索引擎写为name=”BaiduSpider”。content部分有四个指令选项:index、noindex、follow、nofollow,指令间以“,”分隔。
index指令告诉搜索机器人抓取该页面;
follow指令表示搜索机器人可以沿着该页面上的链接继续抓取下去;
Robots Meta标签的缺省值是index和follow,只有inktomi除外,对于它,缺省值是index、nofollow。
注意事项
上述的robots.txt和Robots Meta标签限制搜索引擎机器人(ROBOTS)抓取站点内容的办法只是一种规则,需要搜索引擎机器人的配合才行,并不是每个ROBOTS都遵守的。目前看来,绝大多数的搜索引擎机器人都遵守robots.txt的规则,而对于Robots META标签,支持的并不多,但是正在逐渐增加,如著名搜索引擎GOOGLE就完全支持,而且GOOGLE还增加了一个指令“archive”,可以限制GOOGLE是否保留网页快照。
位置
robots.txt文件应该放置在网站根目录下。举例来说,当spider访问一个网站时,首先会检查该网站中是否存在robots.txt这个文件,如果 Spider找到这个文件,它就会根据这个文件的内容,来确定它访问权限的范围。
wordpress的robots位置
没有在wordpress网站根节目上传过robots.txt,当搜寻引擎和用户拜访某个文件时,wordpress程序会主动生成一个robots.txt给搜寻引擎和用户;若是我们上传编写的robots.txt到网站根节目,用户和搜寻引擎蛛蛛拜访的就是我们上传的文件,wordpress就不会再产生那个文件了。只有服务器找不到robots的时候wordpress才会生成这个文件。
产生
robots.txt并不是某一个公司制定的,而是早在20世纪93、94年就早已出现,当时还没有Google。真实Robots协议的起源,是在互联网从业人员的公开邮件组里面讨论并且诞生的。即便是今天,互联网领域的相关问题也仍然是在一些专门的邮件组中讨论,并产生(主要是在美国)。
1994年6月30日,在经过搜索引擎人员以及被搜索引擎抓取的网站站长共同讨论后,正式发布了一份行业规范,即robots.txt协议。在此之前,相关人员一直在起草这份文档,并在世界互联网技术邮件组发布后,这一协议被几乎所有的搜索引擎采用,包括最早的altavista,infoseek,后来的google,bing,以及中国的百度,搜搜,搜狗等公司也相继采用并严格遵循。
Robot,又称Spider,是搜索引擎自动获取网页信息的电脑程序的通称。Robots协议的核心思想就是要求Robot程序不要去检索那些站长们不希望被直接搜索到的内容。将约束Robot程序的具体方法规范成格式代码,就成了Robots协议。一般来说,网站是通过Robots.txt文件来实现Robots协议。
自有搜索引擎之日起,Robots协议已是一种目前为止最有效的方式,用自律维持着网站与搜索引擎之间的平衡,让两者之间的利益不致过度倾斜。它就像一个钟摆,让互联网上的搜索与被搜索和谐相处。
如有搜索引擎对网站抓取造成负担,可禁用示例:
User-agent: 该搜索引擎UserAgent
Disallow: 禁止抓取的目录
Sitemap: http://网站域名/sitemap.xml

Apache htaccess详解

1 . 如何让的本地APACHE器.htaccess
如何让的本地APACHE器".htaccess"呢?其实只要简朴修改一下apache的httpd.conf设置就让APACHE.htaccess了,来看看操作
打开httpd.conf(在那里? APACHE目录的CONF目录里面),用文本编纂器打开后,查找
(1)
Options FollowSymLinks
AllowOverride None
改为
Options FollowSymLinks
AllowOverride All
(2)去掉下面的注释
LoadModule rewrite_module modules/mod_rewrite.so
就了
2. htaccess 写法
  Apache中的.htaccess(或者”分布式配置”了针对目录改变配置的方法,即,在特定的文档目录中放置包含或多个指令的,以作用于此目录及其子目录。作为,所能的命令受到限制。***Apache的AllowOverride指令来设置。
  子目录中的指令会笼盖更高级目录或者主器配置中的指令。
  .htaccess必需以ASCII模式上传,最好将其权限设置为644。
  错误文档的定位
  常用的客户端哀求错误返回代码:
  401 Authorization Required
  403 Forbidden
  404 Not Found
  405 Method Not Allowed
  408 Request Timed Out
  411 Content Length Required
  412 Precondition Failed
  413 Request Entity Too Long
  414 Request URI Too Long
  415 Unsupported Media Type
  常见的器错误返回代码:
  500 Internal Server Error
  利用.htaccess指定事先制作好的错误提醒页面。一般下,人们专门设立目录,例如errors放置页面。然后再.htaccess中,加入如下的指令:
  ErrorDocument 404 /errors/notfound.html
  ErrorDocument 500 /errors/internalerror.html
  一条指令一行。上述第一条指令的意思是对于404,也找到所的文档的得显示页面为/errors目录下的notfound.html页面。不难看出语法格局为:
  ErrorDocument 错误代码 /目录名/名.扩展名
  所提示的很少的话,不必专门制作页面,直接在指令中HTML号了,例如下面例子:
  ErrorDocument 401 “你权限访问该页面,请抛却!”
  文档访问的密码保护
  要利用.htaccess对某个目录下的文档设定访问和对应的密码,首先要做的是生成.htpasswd的文本文档,例如:
  zheng:y4E7Ep8e7EYV
  这里密码经由加密,找些工具将密码加密成.htaccess的编码。该文档最好不要放在www目录下,建议放在www根目录文档之外,这样更为安全些。
  有了授权文档,在.htaccess中加入如下指令了:
  AuthUserFile .htpasswd的器目录
  AuthGroupFile /dev/null (授权访问的目录)
  AuthName EnterPassword
  AuthType Basic (授权类型)
  是的主人,应该处处为着想。 —— 雷锋
  require user wsabstract (允许访问的,但愿表中都允许, require valid-user)
  注,括号部门为学习添加的注释
  拒绝来自某个IP的访问
  我不想某个政府部门访问到站点的,那.htaccess中加入该部门的IP而将它们拒绝在外。
  例如:
  order allow,deny
  deny from 210.10.56.32
  deny from 219.5.45.
  allow from all
  第二行拒绝某个IP,第三行拒绝某个IP段,也219.5.45.0~219.2.45.255
  想要拒绝人?用deny from all好了。不止用IP,也用域名来设定。
  保护.htaccess文档
  在.htaccess来设置目录的密码保护时,它包含了密码的路径。从安全考虑,有必要把.htaccess也保护起来,不让别人看到其中的。虽然用其他做到这点,好比文档的权限。不外,.htaccess本身也能做到,只需加入如下的指令:
  order allow,deny
  deny from all
  URL转向
  可能对重新规划,将文档了迁移,或者更改了目录。这,来自搜索引擎或者其他链接过来的访问就可能犯错。这种下,如下指令来完成旧的URL自动转向到新的:
  Redirect /旧目录/旧文档名 新文档的
  或者整个目录的转向:
  Redirect 旧目录 新目录
  改变缺省的首页
  一般下缺省的首页名有default、index等。不外,有些目录中没出缺省,而是某个特定的名,好比在pmwiki中是 pmwiki.php。这种下,要记住名来访问很麻烦。在.htaccess中等闲的设置新的缺省名:
  DirectoryIndex 新的缺省名
  也列出多个,顺序表明它们之间的优先级别,例如:
  DirectoryIndex filename.html index.cgi index.pl default.htm
  防止盗链
  不喜欢别人在的网页上连接的、文档的话,也htaccess的指令来做到。
  所的指令如下:
  RewriteEngine on
  RewriteCond %{ HTTP_REFERER } !$
  RewriteCond %{ HTTP_REFERER } !http://(www.)?mydomain.com/.*$ [NC]
  RewriteRule .(gif&line;jpg)$ - [F]
  觉得让别人的页面开个天窗不好看,那用一张来代替:
  RewriteEngine on
  RewriteCond %{ HTTP_REFERER } !$
  RewriteCond %{ HTTP_REFERER } !http://(www.)?mydomain.com/.*$ [NC]
  RewriteRule .(gif&line;jpg)$ http://www.mydomain.com/替代名 [R,L]
其它补充:
在给出如何配置Apache支持.htaccess文件之前,首先申明一下:使用.htaccess文件,会降低httpd服务器的一点性能。
配置方法
找到Apache的httpd.conf配置文件,编辑器打开。
<Directory />
  Options FollowSymLinks
  AllowOverride None
</Directory>
<Directory />
  Options FollowSymLinks
  AllowOverride All
</Directory>
如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。
例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:
*/
AccessFileName .config  通常,.htaccess文件使用的配置语法和主配置文件一样。AllowOverride指令按类别决定了.htaccess文件中哪些指令才是有效的。
(不)使用.htaccess文件的场合
  一般情况下,不应该使用.htaccess文件,除非你对主配置文件没有访问权限。有一种很常见的误解,认为用户认证只能通过.htaccess文件实现,其实并不是这样,把用户认证写在主配置文件中是完全可行的,而且是一种很好的方法。
  .htaccess文件应该被用在内容提供者需要针对特定目录改变服务器的配置而又没有root权限的情况下。如果服务器管理员不愿意频繁修改配置,则可以允许用户通过.htaccess文件自己修改配置,尤其是ISP在同一个机器上运行了多个用户站点,而又希望用户可以自己改变配置的情况下。
  虽然如此,一般都应该尽可能地避免使用.htaccess文件。任何希望放在.htaccess文件中的配置,都可以放在主配置文件的段中,而且更高效。
避免使用.htaccess文件有两个主要原因。
  首先是性能。如果AllowOverride启用了.htaccess文件,则Apache需要在每个目录中查找.htaccess文件,因此,无论是否真正用到,启用.htaccess都会导致性能的下降。另外,对每一个请求,都需要读取一次.htaccess文件。
  还有,Apache必须在所有上级的目录中查找.htaccess文件,以使所有有效的指令都起作用,所以,如果请求/ctusky/ctu/sky中的页面,Apache必须查找以下文件:
  其次是安全。这样会允许用户自己修改服务器的配置,这可能会导致某些意想不到的修改,所以请认真考虑是否应当给予用户这样的特权。

Sitemap详解

Google、雅虎、和微软都支持一个被称为xml网站地图(xml Sitemaps)的协议,而百度Sitemap是指百度支持的收录标准,在原有协议上做出了扩展。百度sitemap的作用是通过Sitemap告诉百度蜘蛛全面的站点链接,优化自己的网站。百度Sitemap分为三种格式:txt文本格式、xml格式、Sitemap索引格式。
优化步骤
1,我们需要为每一个页面链接介绍一段简短的文字,这样可以提示这部分内容是关于哪方面的。
2,要为谷歌,百度这样的搜索引擎提供一条"绿色的通道"为蜘蛛提供可以浏览整个网站的链接,使搜索引擎能迅速收录网站的主要的网页,例如首页,详细页及帮助等页面。
3,如果用户已经在你网站上搜索过某些文章或信息,此时就需要有一个关于已经查看过的页面或列表.如果没有这些程序,那么你需要做一个文字链接到某个页面并且这个页面是可以得到所有想查询的内容链接以便告诉用户如何去查找他们需要查找的信息。
4,如果你网站的链接因为某些原因例如链接失效过无法获得原来链接的话,此时你就需要做一个错误页面的转向,这个错误的转向页面你也可以充分发挥你的想象力以便做的更加漂亮。
5,这一点很重要,你可以在网站地图的文本和超级链接里提到你要优化的主要的关键词,以便帮助搜索引擎来识别。
6,间接的帮助搜索引擎能够轻轻松松索引到一些动态的页面,最好此时的动态页面你将其为伪静态化,当然静态化是最好的了,因为搜索引擎最喜欢静态化的页面。
格式
Google SiteMap
Google SiteMap Protocol是Google自己推出的一种站点地图协议,此协议文件基于早期的robots.txt文件协议,并有所升级。在Google官方指南中指出加入了Google SiteMap文件的网站将更有利于Google网页爬行机器人的爬行索引,这样将提高索引网站内容的效率和准确度。文件协议应用了简单的XML格式,一共用到6个标签,其中关键标签包括链接地址、更新时间、更新频率和索引优先权。[1]
网址2005-06-03T04:20-08:00always1.0网址2005-06-02T20:20:36Zdaily0.8
百度sitemap
网页地址2010-01-01daily1.0
XML标签
changefreq:页面内容更新频率。
lastmod:页面最后修改时间
loc:页面永久链接地址
priority:相对于其他页面的优先权
url:相对于前4个标签的父标签
urlset:相对于前5个标签的父标签
我将一句一句分解讲解这个xml文件的每一个标签:
<urlset xmlns="
这一行定义了此xml文件的命名空间,相当于网页文件中的<html>标签一样的作用。
这是具体某一个链接的定义入口,你所希望展示在SiteMap文件中的每一个链接都要用<url>和</url>包含在里面,这是必须的。
用<loc>描述出具体的链接地址,这里需要注意的是链接地址中的一些特殊字符必须转换为XML(HTML)定义的转义字符,如下表: 字符 转义后的字符
HTML字符 字符编码
& 符号 & &
单引号 ' '
双引号 " "
大于 > >
小于 < <
2005-06-03T04:20:32-08:00
<lastmod>是用来指定该链接的最后更新时间,这个很重要。Google的机器人会在索引此链接前先和上次索引记录的最后更新时间进行比较,如果时间一样就会跳过不再索引。所以如果你的链接内容基于上次Google索引时的内容有所改变,应该更新该时间,让Google下次索引时会重新对该链接内容进行分析和提取关键字。这里必须用ISO 8601中指定的时间格式进行描述,格式化的时间格式如下:
年:YYYY(2005)
年和月:YYYY-MM(2005-06)
年月日:YYYY-MM-DD(2005-06-04)
年月日小时分钟:YYYY-MM-DDThh:mmTZD(2005-06-04T10:37+08:00)
年月日小时分钟秒:YYYY-MM-DDThh:mmTZD(2005-06-04T10:37:30+08:00)
这里需注意的是TZD,TZD指定就是本地时间区域标记,像中国就是+08:00了
always
用这个标签告诉Google此链接可能会出现的更新频率,比如首页肯定就要用always(经常),而对于很久前的链接或者不再更新内容的链接就可以用yearly(每年)。这里可以用来描述的单词共这几个:"always", "hourly", "daily", "weekly", "monthly", "yearly",具体含义我就不用解释了吧,光看单词的意思就明白了。
1.0
<priority>是用来指定此链接相对于其他链接的优先权比值,此值定于0.0 - 1.0之间
还有</url>和</urlset>,这两个就是来关闭xml标签的,这和HTML中的</body>和</html>是一个道理
另外需要注意的是,这个xml文件必须是utf-8的编码格式,不管你是手动生成还是通过代码生成,建议最好检查一下xml文件是否是utf-8编码,最简单的方法就是用记事本打开xml然后另存为时选择编码(或转换器)为UTF-8。
登陆Google提交你的SiteMap文件,链接,如果还没有注册或者登陆Google,就先用自己的帐号登陆Google,登陆后转到Your Sitemaps状态页面,可以点击那个Add a Sitemap + 跳转到提交页面进行Sitemap文件的提交。建议文件放在你的站点根目录下。给Google提交你的Sitemap URL后可以看见在列表里已存在,不过这时候还没有生效,必须过几个小时后Status栏变成OK表示正式生效,如果不是OK,可以查看Google给出的状态标示解释看看是什么原因。[1]
作用
介绍
网络抓取工具通常会通过网站内部和其他网站上的链接查找网页。
Sitemap 会提供此数据以便允许支持 Sitemap 的抓取工具抓取 Sitemap 提供的所有网址,并了解使用相关元数据的网址。使用 Sitemap协议并不能保证网页会包含在搜索引擎中,但可向网络抓取工具提供一些提示以便它们更有效地抓取网站。
应用
Sitemap 0.90 是依据创意公用授权-相同方式共享(Attribution-ShareAlike Creative Commons License) 的条款提供的,并被广泛采用,受 Google、Yahoo! 和 Microsoft 在内的众多厂商的支持。
生成
步骤
方法一:
1.打开浏览器输入在线生成Sitemap网站的网址;
2.在表单里面填入要生成sitemap的网页的网址,然后点击提交;
3.打开了生成的数据结果页面,复制文本框里面的代码;
4.新建一个文本文件把代码粘贴进去,然后另存为utf-8格式的文件,文件名为sitemap.xml,然后把这个文件上传到自己网站的对应的根目录下面;
5.打开浏览器输入网址 ,点击右上角的登陆,用自己的google帐户登陆,还没有 Google 帐户? 创建一个帐户 ,注册帐户然后登陆帐户;
6.登陆成功以后,点击进入用户管理中心,然后点击:网站管理员工具;
7.首先添加你的网址链接 ,添加成功以后,在网址的对应项后面点击添加,打开sitemap的添加页面,选择下拉菜单,选择普通网站地图,下面出现文本表单,在空白表单后面添加sitemap.xml,然后点击提交;
8.好了!sitemap提交成功,等待5个小时之内google收录你的网站!
方法二:
1.到在线生成sitemap网站下载软件:
此类工具需要下载到本地生成地图,生成速度较快。
2.运行软件生成sitemap文件:工程还有新建那两栏随便写,例如"sitemapx" "hongdex" 都行,确认后,显示基本信息,直接默认,点击下一步,接着点击抓取网页。网页抓取完直接点击生成,接着点复制文件,选取路径。sitemap的文件就这样制作完成了;
3.通过FTP提交sitemap文件到网站根目录:这个应该都会的了,不懂的可以直接百度搜索”如何通过ftp工具提交文件“等类似关键词;
4.登陆Google网站管理员工具提交网站地图sitemap文件:前提已经有注册google账号跟添加了网站,控制台首页那显示sitemaps一栏,直接点击,提交网站前输入”sitemap.xml“ ,最后直接点击提交网站。步骤完成!最后等着谷歌收录网站页面了。
至于百度蜘蛛则是html格式
Sitemap的使用和登陆google
使用Google sitemap能提高网站/网页在SERP中的排名(或提高SEO效果) Sitemaps只是在一定程度上提高网站页面被收录、索引的效率,从这个意义上说,对网站的整体SEO效果当然是有所助益的。
但是,Sitemaps与网站/网页最终出现在SERP中的排名则没有任何直接意义上的联系,这是两个虽有联系但实现过程中交叉部分很少的两个机制。——当然,如果非要强辩说,随着网站内页面收录数量增加,站内的交叉链接权值会相应提高,而这会对最终的排名产生影响,倒也能在某种程度上说得过去,不过,影响多大就难说了。
使用方法
第一步:添加网站,验证网站归属,等待审核
·登录后点击“添加网站”。若网站删除或更换域名,则需重新提交;
·点击“验证此网站”,选择验证方式并获取验证文件,完成验证;
· 验证方式一:文件验证;
· 验证方式二:HTML标签验证;
·等待管理员审核。主要审核网站属性、网站内容质量等。审核最长可能需要一天时间。
第二步:通过点击“数据管理”,添加新数据
如何添加新数据
·选择数据的类型,根据类型对应的xml格式规范部署您的数据文件;
·为您的数据指定更新周期;
·按照xml格式规范部署好文件后,在地址栏填写文件存放地址,点击提交即可。
我们对文件的处理时间长短将视文件大小而定。
如何手动更新已提交的数据
·如果您想在指定更新周期以外,手动通知我们数据有更新,可以在“数据管理”页面选中要手动更新的文件并点击“更新所选”即可;
·如果数据存在错误或不符合协议格式,则状态栏会显示为错误,请参考平台提示修改并更新;
·您可通过平台查看数据的统计信息,包括已抓取数量,最新处理时间等。
注:百度对已提交的数据,不保证一定会抓取及索引所有网址,并且不保证其排名。
注意要点
全部链接真实有效
地图的主要目的是方便搜索引擎蜘蛛抓取的,如果地图存在死链或坏链,会影响网站在搜索引擎中网站权重的,所以要仔细检查有无错误的链接地址,提交前通过站长工具,检查网站的链接是否有效。
简化网站地图
网站地图不要出现重复的链接,要采用标准W3格式的地图文件,布局要简洁,清晰,如果地图是内容式地图,每页不要超过100内容个链接,采用分页的行式,逐一开来,这样方便搜索引擎蜘蛛逐页爬行。
更新网站地图
建议经常更新网站地图,经常的更新地图,便于培养搜索引擎蜘蛛爬行的粘度。经常有新的地图内容生成,长期以来,蜘蛛就会更关注,培养蜘蛛的爬行规则,这样网站内容能更快的被搜索引擎抓取收录。
百度sitemap工具升级改名公告
新链接提交工具将功能整体分为两部分:自动提交和手动提交;自动提交里又分实时推送和sitemap。[2]
百度三种链接提交方式的区别
  1.主动推送的收录速度是最快的,我们建议您定期将网站内新增高质链接通过此方式推送给百度,以保证该链接及时被百度发现。注意是新增高质链接哦,如果多次提交历史链接、低质链接,会导致我们不再信任您提交的数据。
  2.sitemap功能可以用来向百度提交历史数据和重要数据,或者将一些定期例行更新的网页通过sitemap提交给百度。
  3.在实时推送和sitemap出现问题时,或者新制作的专题页无法通过实时推送提交时,手工提交也是值得信任的工具哦。
* 声明:本文由其作者或媒体撰写,观点仅代表其本身,不代表本站立场。
编辑
HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com HappyLifeLife.com
 
<< < - > >>
[Web][*] [JAVA][*] [JS][*] [GIT][*] [C][*] [Android][*] [0][*] [TL][*] [DB][*] [O][*] [3D][*] [PAS][*] [IOS][*] [算法][*] [地球][*] [学习方法][*] [探索][*] [宇宙][*] [Linux][*] [阅读秘诀][*] [考试技巧][*] [...]
天天快乐生活[HappyLifeLife.com]
欢迎来访 快乐空间 热点新闻 我的分享 读书频道 七彩生活 精彩世界 快乐搜索 
ICP备15040518 | ©1999-2018 HappyLiveLife.com 版权所有 | 服务 | 爱新闻 | 爱分享 | 在线搜索 | 招贤纳士
欢迎来访 快乐空间 热点新闻 我的分享 读书频道 七彩生活 精彩世界 快乐搜索 
ICP备15040518 | ©1999-2018 HappyLiveLife.com 版权所有 | 服务 | 爱新闻 | 爱分享 | 在线搜索 | 招贤纳士