网页制作中html5和微信小程序切图的区别

在做html5切图和小程序切图的时候,有哪些区别?其实本质差不多,小程序的样式文件wxss 对css做了少许改变,小程序的wxml则是 xml的基础上做了小许改变,所以如果你对html5/css3足够了解的话,在小程序代码中看到大量的html5的影子。

但是需要了解html5和微信小程序的不同切图的规则。

一、微信小程序和HTML5的标签区别:

 

网页制作中html5和微信小程序切图的区别

 

 

二、wxss 选择器

HTML5 微信小程序

div(标签选择器) view、text、icon、input、image、navigator(标签选择器)

class(类选择器) class

id(id选择器)(效率最高) id(效率最高)

element,element(层级选择器) element,element(层级选择器)

:after(伪类选择器) :after :before

:frist-child等 :frist-child等(不建议(工具过滤易导致页面错乱))

.class .class .class .class(不建议(工具过滤易导致页面错乱))

群组选择器 群组选择器

后代选择器 后代选择器

三、placeholder的区别

小程序中可以直接给placeholder添加样式

四、自适应区别

1、我们用html5写自适应的话需要用到百分比或是函数计算比例,但小程序可以让我们避免了这个麻烦,我们可以用rpx,在ipoone6的开发环境下,1rpx=0.5px;我们采用这个单位就可以在完成后,省掉兼容的一部分问题了。(当然我这里面没有考虑到)

2、这里有个开发中可能遇到的坑,由于背景图是全覆盖的,所以这里可以在wxss文件中添加语句:.indexBox{height:100%;} page{height:100%} 都需要设置,要不然没法自适应,注意大小写。

eyoucms图集分页 | volist标签分页

eyoucms的图集在很多时候充当相册功能的作用,调用的话也很简单volist标签循环输出就可以,痛就痛在这个volist标签分页居然不支持,怎么办?

以下办法通过前端切割数据进行显示,配合eyoucms静态缓存清除,达到前端图集分页的目的:

地表最强eyoucms图集分页代码

一、数据处理:

{eyou:arclist row=’1′ titlelen=’30’}
{eyou:arcview id=’field4′}
{php}
$p_num = 3; //每页显示条数
$p_btn = 2; //分页按钮整数阈值,越大显示越多
$p_con = $field4[image_list]; //图集json
$ck = ‘page’.$field4[typeid];
$thenum = $_COOKIE[$ck];
if(!$thenum){ $thenum = 1; }
$p_totle = count($p_con);
$p_list = [1];
if($p_totle > $p_num && $p_num > 0) {
$p_con = array_slice($p_con, ($thenum-1)*$p_num, $p_num); //内容切割
$p_all = $p_totle/$p_num;
$p_allint = intval($p_all);
$p_all = $p_all > $p_allint ? $p_allint+1 : $p_allint;
for ($c = 0; $c < $p_all; $c += 1) {
if($c >= $thenum-$p_btn && $c < $thenum+($p_btn-1)) {
$p_list[$c] = $c+1;
}
}
$p_list[$p_all-1] = $p_all;
}
{/php}
<script type=”text/javascript”>
//放在变量$ck之后,在列表渲染之前刷新
var url = window.location.href;
theurl = url.indexOf(“clear”);
var clear = url+’&clear=1′;
var ck = document.cookie.indexOf(“{$ck}=”);
if(ck == -1 && theurl == -1){
location.replace(clear);
}
function page(obj) {
document.cookie=”{$ck}=”+obj.title;
theurl == -1 ? location.replace(clear) : location.reload();
}
</script>

{eyou:volist name=”$p_con” id=’field5′}
<li class=”projectitem”>
<a rel=”nofollow” href=”{$field5.image_url}” target=”_blank” class=”item_link”>
<div class=”project_img”>
<img src=”{$field5.image_url|thumb_img=###,500,320,3}” />
</div>
<div class=”project_info”>
<div>
<p class=”title”>{$field4.title}</p>
<p class=”subtitle”>{$field5.intro}</p>
</div>
</div>
</a>
<a rel=”nofollow” href=”javascript:;” target=”_blank” class=”details”>more</a>
</li>
{/eyou:volist}
{/eyou:arcview}
{/eyou:arclist}

二、分页的输出:

{eyou:foreach name=’$p_list’ item=’p’}
<a rel=”nofollow” href=”javascript:;”{eyou:eq name=’$thenum’ value=’$p’} class=”active”{/eyou:eq} title=”{$p}” onclick=”page(this)”>{$p}</a>
{/eyou:foreach}
———————————–
最后,明白这个原理,作用就不仅仅是图集了,任何数据输出,都可以用这个超级代码进行切割分页显示。

DEDECMS手机站如何AJAX提交数据到自定义表单

需求:手机站要点击某一个按钮后,弹出一个留言框,让用户留下姓名和电话号码

首先:后台自定义表单内添加表单,,多的不解释,字段添加好了后,下面是重点

根据: http://www.moke8.com/article-12258-1.html 这个教程修改你的自定义表单字段

比如我修改成了这样子.

《开始》

<div class=”phone_form”>
<form action=”javascript:;” enctype=”multipart/form-data” method=”post”>
<input type=”hidden” name=”action” value=”post” />
<input type=”hidden” name=”diyid” value=”1″ />
<input type=”hidden” name=”do” value=”2″ />

<label>姓名:<input type=”text” id=”name” name=”name” value=”” /></label>
<label>手机:<input type=”text” id=”phone” name=”phone” value=”” /></label>

<input type=”hidden” name=”dede_fields” value=”name,textchar;phone,textchar;” />
<input type=”button” class=”submit fr” value=”提 交” onclick=”add_ajaxmessage()”/>
</form>
</div>
<script type=”text/javascript” src=”726/js/jquery-1.10.1.min.js”></script>
<script type=”text/javascript”>
function add_ajaxmessage(){
var name=document.getElementById(“name”);
var phone=document.getElementById(“phone”);

//定义变量接收上面表单每项的值和几个dede隐藏的input的值
var dataString = ‘name=’+ name.value + ‘&phone=’ + phone.value +’&action=post’+ ‘&diyid=1&do=2&dede_fields=name,textchar;phone,textchar’;
$.ajax({
type: “POST”,
url: “diy.php”, //提交到后台文件
data: dataString, //传值
success: function(data) {

alert(data);//成功打印PHP返回的值

}
});
return false;
}
</script>

 

《结束》

复制一份plus/diy.php到m(手机站根目录)下,然后修改

把这一行代码注释掉,,

alert显示提交成功后基本上就可以在后台看到提交的数据了

,至于后面的jquery加判断之类的..这些可以后期自己去加..

 

eyoucms留言模版验证码实现

eyoucms留言模版验证码实现
效果图如下

1、为什么要在留言模版下加入验证码?
留言模版下加入验证码可以防止恶意攻击,防止用机器把数据库填满
2、实现验证码功能
第一步:找到lists.guestbook.html

第二步:前台留言模型的图形验证码标签调用
比如需要在留言表单里加入图形验证码,复制下方验证码开始到验证码结束在留言标签中 {eyou:guestbookform}。

{eyou:guestbookform type=’default’}
<form method=”POST” enctype=”multipart/form-data” action=”{$field.action}”>
<!– ……此处省略其他表单代码 –>
<div class=’form-group’>
<textarea name=”{$field.attr_1}” id=”attr_1″ placeholder='{$field.itemname_1}’></textarea>
</div>
<!– ……此处省略其他表单代码 –>

<!– 验证码开始 –>
{eyou:notempty name=’$field.IsVertify’}
<div>
<input type=”text” name=”vertify” autocomplete=”off” placeholder=”图片验证码”/>
<img {$field.VertifyData} title=”看不清?点击更换验证码” style=”margin-left: 2px;width: 80px;height: 35px;” />
看不清?<a href=”javascript:void(0);” id=”a_vertify” {$field.VertifyData}>点击更换</a>
</div>
{/eyou:notempty}
<!– 验证码结束 –>

<!– ……此处省略其他表单代码 –>
<div class=”form-group m-b-0″>
<button type=”submit” >提交<button>
</div>
{$field.hidden}
</form>
{/eyou:guestbookform}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
第三步:找到config.php文件

第四步:把config.php文件中的留言提交验证码配置0改为1

然后就完成啦,有帮助的话不妨点个赞吧,谢谢啦!!!

ThinkPHP5.0手把手实现手机阿里云短信验证

最详细教程,没有第二篇

为分享经验而来(菜鸟来围观,大神轻点喷)
简述一下思路:现在有一个简单的手机短信验证页面,代码如下

html代码

  1. <!DOCTYPE html>
  2. <html lang=“en”>
  3. <head>
  4. <meta charset=“UTF-8”>
  5. <title>ThinkPHP5.0短信验证</title>
  6. <script src=“__STATIC__/jquery.js”></script>
  7. </head>
  8. <body>
  9. <form>
  10. <div>
  11. <div>
  12. <input id=“tel” type=“text” placeholder=“手机号”><br>
  13. <input id=“yzm” type=“text” placeholder=“验证码”><input type=“button” id=“sendmsg” value=“获取验证码”>
  14. </div>
  15. <div>
  16. <a href=“#” id=“submit”>验证</a>
  17. </div>
  18. </div>
  19. </form>
  20. </body>
  21. </html>
  22. <script >
  23. /*——————————————-*/
  24. var InterValObj; //timer变量,控制时间
  25. var count = 60; //间隔函数,1秒执行
  26. var curCount;//当前剩余秒数
  27. var code = “”; //验证码
  28. var codeLength = 6;//验证码长度
  29. $(function () {
  30. $(‘#sendmsg’).click(function () {
  31. var tel = $(‘#tel’).val();
  32. $.ajax({
  33. type: “POST”,
  34. url: “{:url(‘index/send_dx’)}”,
  35. data: {tel:tel},
  36. success: function (result) {
  37. if(result == 1){
  38. curCount = count;
  39. //设置button效果,开始计时
  40. $(“#sendmsg”).css(“background-color”, “”);
  41. $(“#sendmsg”).attr(“disabled”, “true”);
  42. $(“#sendmsg”).val(“获取” + curCount + “秒”);
  43. InterValObj = window.setInterval(SetRemainTime, 1000); //启动计时器,1秒执行一次
  44. // alert(“验证码发送成功,请查收!”);
  45. }else{
  46. alert(result);
  47. }
  48. },
  49. dataType: ‘json’
  50. });
  51. });
  52. $(‘#submit’).click(function(){
  53. var yzm = $(‘#yzm’).val();
  54. $.ajax({
  55. url:“{:url(‘index/check_dx’)}”,
  56. data:{yzm:yzm},
  57. type:“post”,
  58. dataType:“json”,
  59. success:function(data){
  60. if(data == 1)
  61. {
  62. alert(“验证成功”);
  63. }else{
  64. alert(data);
  65. }
  66. }
  67. });
  68. });
  69. });
  70. function SetRemainTime() {
  71. if (curCount == 0) {
  72. window.clearInterval(InterValObj);//停止计时器
  73. $(“#sendmsg”).removeAttr(“disabled”);//启用按钮
  74. $(“#sendmsg”).css(“background-color”, “”);
  75. $(“#sendmsg”).val(“重发验证码”);
  76. code = “”; //清除验证码。如果不清除,过时间后,输入收到的验证码依然有效
  77. }
  78. else {
  79. curCount–;
  80. $(“#sendmsg”).val(“获取” + curCount + “秒”);
  81. }
  82. }
  83. </script>

控制器代码

  1. <?php
  2. namespace app\index\controller;
  3. use think\Controller;
  4. use think\Loader;
  5. class Index extends Controller
  6. {
  7. public function index()
  8. {
  9. return $this->fetch();
  10. }
  11. public function send_dx()
  12. {
  13. // 加载extend文件夹里面的文件
  14. Loader::import(‘dx.api_demo.SmsDemo’,EXTEND_PATH);
  15. $tel = input(‘post.tel’);
  16. $code = rand(100000,999999);
  17. // 调用示例:
  18. set_time_limit(0);
  19. header(‘Content-Type: text/plain; charset=utf-8’);
  20. $response = (new \SmsDemo)::sendSms($tel,$code);
  21. $response = (new \SmsDemo)::sendBatchSms();
  22. $response = (new \SmsDemo)::querySendDetails($tel);
  23. // 保存验证码
  24. session(‘code’,$code);
  25. return 1;
  26. }
  27. public function check_dx()
  28. {
  29. $yzm = input(‘post.yzm’);
  30. if($yzm == session(‘code’))
  31. {
  32. session(‘code’,null);
  33. return 1;
  34. }
  35. return “验证码错误”;
  36. }
  37. }

当我们点击获取验证码时,我们填的手机会收到一条短信,并且我输入手机发来的验证码正确输入到验证码输入框后点击验证,就跳转到了我们想要的页面。


思路理清了就开始我们的教学步骤吧

1、登录到www.aliyun.com首页,右上角导航找到控制台点击进入。

2、在控制台首页左上角导航找到产品与服务二级导航再找到云通信栏目下的短信服务点击进入。

3、在短信服务控制台页面左侧找到应用开发完成应用开发栏目下的接口调用,签名管理,模板管理三步操作,我们的任务就完成了一半了。

(1)接口调用:获取AK,点击AccessKey按钮,如果没有创建过访问密钥(AK),点击创建AccessKey,验证后就可以了。

(2)添加签名:我们还需要添加一个签名作为发出短信的标题,一般个人用户使用自己的真实姓名、网站名通过率较高,申请说明:可以使用固定句子手机验证码或短信验证,当然可以使用其他申请理由,申请后等待小小会儿,在等待过程可以先完成模板管理

(3)模板管理:模板类型看个人需求,我们这里选验证码;模板名称可以随便起,它的作用只是方便用户管理自己的模板;模板内容可以点击常用模板库选择自己想要的模板,也可以自己定义;申请理由同上一步,使用固定句子就可以了。

4、 回到短信服务控制台页面在右边头像下面?申请短信模板选择SDK及DEMO下载,进入下载页面后找到并点击下载标题下的【PHP】蓝色字样,将下载的压缩包解压这里我们取名为“dx”,后面才是重头戏。

5、 把解压好的文件夹(dx)放在ThinkPHP项目根目录下的extend目录下,开始操作dx文件夹里面的文件。

6、 用sublime打开dx,修改dx/api_demo/SmsDemo.php,我们需要把之前在阿里云申请的信息填写到这里,具体步骤看截图吧,跟着截图先把这个小功能实现了,后面再把这个小功能修改成自己的东西。

设置API接口
设置发送短信
设置接受号码
代码搬家


看这里:完成以上步骤加上代码,相信看完的朋友已经心中有数了!!! 如果本文对你有一点点帮助,可以帮我点个赞吗 你们的认可是我前进的动力

有一些朋友可能还有不懂的,可以及时联系我,我的邮箱1279728601@qq.com,大家一起进步

建材网站建设解决方案

如何定位和展现建材企业的网络形象?让消费者能有全面清晰的认知?

如何表现建材企业的特色和服务品质,以区别于同行,获得更多精准消费者的认可?

如何利用网站与线下销售相结合,将消费者带到网络上,享受更好的服务,并长期粘滞住消费者?

如何通过网络营销带来更多的消费者,形成大面积良好的口碑效应,让消费者安全放心地消费?

建材行业网站建设的服务范围

网站定位分析及建议,包含网站策划布局和结构,形成一整套解决方案;

建材行业网站的形象界面创意设计以及DIV前台结构布局;

系统性的架构策略、程序模块功能分析、运营维护策略、培训及知识转移计划等;

可延展性分析、可扩充性考虑以及系统稳定性分析报告;

网站运营维护方案。根据企业的管理模式,建议网站日常信息提供、审核、发布的一整套运转方案,协助企业高效管理网站;

网站的营销推广计划,网站运维策略及网站价值分析、盈利情况分析等等;

建材网站建设模块设置

项目 模块内容详情
个性化页面建设 建材网站的页面设计应符合产品及其客户的需求:建材的厚重,钢铁的银白,营销的热情等等。
建材网站可自由编辑物品上下架、装修、调价及促销广告。
检索 (1)产品搜索:能让顾客按关键字、类别、促销宝贝、品牌、价格区间来组合搜索宝贝。保证每个页面都有搜索条。
(2)热门搜索词管理:顾客在搜索条内输入信息时,自动弹出下拉菜单显示热门搜索词。可仿照淘宝。
相关商品 在某件商品描述底部或者侧栏展示相关产品推荐。
购物车 仿照淘宝购物车的方式。进入购物车后,可查看商品单价,可进行商品数量修改、删除。
商品上传 建材网站所有者可进行单件商品上传,也可进行批量上传,上传后的宝贝可进行管理。
商品分类 目前主营产品家居建材、日后产品类型会拓展。所以后台可进行商品大类的新增与管理,并能根据自己需要设置3级子分类。
支付方式 采用支付宝网银在线支付方式,网银在线自动转账支付业务。
流量统计 安装百度统计,cnzz等第三方平台统计代码方便查阅数据。
排行榜 前台首页显示“销售排行榜”和“点击排行版”,为顾客提供购买参考信息。
商品排序 在顾客浏览商品时,可根据价格、新品、销量、人气对商品进行排序。
在线客服 载入QQ做客服沟通工具(QQ必须具备管理员与店铺后台沟通,店铺与买方沟通,商城客服沟通)
订单管理 可浏览、修改、关闭订单的详细信息
库存提醒 可设置当某件商品库存低于多少件时,进行库存提醒。
缺货登记 缺货的商品系统能自动登记,也可人工手动添加。
促销模板 提供多种促销模板以保证建材网站各种促销活动,以下几个必须具备:送、券、礼、分、折、免
可拓展版块 可以随着业务的需求,拓展一些新的版块,如话费充值和买火车票、汽车票等。
友情链接 提供相关网站的友情链接。

dedecms(织梦)数据提交防csrf请求校验

前言
很多人喜欢直接在前端写ajax向后台指定地址提交数据,这样的做法过于草率,当时可能比较省事,后面付出的代价必定是惨痛的。笔者曾“有幸”经历过几次这样的跨域攻击,服务器遇到来自四面八方的海量请求,瞬间崩溃,日志显示请求来自不同国家和城市,这样一来常用的IP防火墙策略收效甚微。最终发现,服务器诸多接口安全性过低,省去了诸多校验,看似化繁为简,实则漏洞百出,攻击者在网上收集“肉鸡”,同时向指定服务器发送请求,致使服务器瘫痪。本文通过常用的dede(织梦)二次开发,
展示安全程度较高的前台数据提交策略,抛砖引玉,望读者日常开发过程勿避重就轻,忽视数据与信息安全。
环境与需求

  1. Centos 6.8
  2. LANMP
  3. DEDEV5.7
    4 .需求:使用dede创建自定义表单,前台向后台自定义表单提交数据。 代码实现
    切换到dede根目录 创建自定义标签解析文件 /include/taglib/csrftoken.lib.php

<?php
require_once(dirname(FILE).”/../helpers/cache.helper.php”);
if(!defined(‘DEDEINC’)){
exit(“Request Error!”);
}
/**

  • 自定义csrf_token生成标签
    *
  • @version $Id: csrftoken.lib.php 1 10:11 2018年1月9日
  • @package DedeCMS.Taglib
  • @copyright Copyright (c) 2007 – 2010, DesDev, Inc.
  • @author underclounds underclounds@gmail.com
  • @license http://help.dedecms.com/usersguide/license.html
  • @link http://www.dedecms.com
    */

/*>>dede>>
csrf签名标签
全局标记
V55,V56,V57
生成指定长度的随机加密字符串,每十分钟过期一次,用于前后台数据交互的验证 防止csrf攻击
{dede:csrftoken name=’token名 默认csrf’ len=’长度 默认12位’ exp=’过期时间 默认600秒’ /}

dede>>*/

function lib_csrftoken(&$ctag,&$refObj)
{
global $dsql,$envs;

//读取sessionId
@session_start();
$sessionId = session_id();

//属性处理
$attlist="name|csrf_token,len|12,exp|600";

//填充属性默认值
FillAttsDefault($ctag->CAttribute->Items,$attlist);

//读取标签属性
$name = $ctag -> GetAtt('name');
$len = (int) $ctag -> GetAtt('len');
$expires = (int) $ctag -> GetAtt('exp');

//读取缓存token
$cacheToken = GetCache($sessionId, $name);
if(empty($cacheToken)) {
    //生成token
    $token = randStr($len);

    //将token存入缓存
    $token = substr(sha1($token), 3, 32);
    SetCache($sessionId, $name, $token, $expires);
} else {
    $token = $cacheToken;
}
return $token;

}

/**

  • 生成随机字符串
  • @param $len int 长度
  • @return string
    */
    function randStr($len)
    {
    $str = ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789’;
    $token = ”;
    for($i=0; $i<$len; $i++)
    {
    $token .= $str[rand(0,strlen($str)-1)];
    }
    return $token;
    }
    创建处理ajax请求文件 /plus/ajaxOrder.php

<?php
//header(“Access-Control-Allow-Origin:*”);//释放跨域
require_once(dirname(FILE).”/../include/common.inc.php”);
require_once(dirname(FILE).”/../include/helpers/cache.helper.php”);
global $dsql;

/**

  • ———————————————
  • Class ajaxOrder
  • 处理ajax提交的用户预约信息
  • @name ajax
  • @package ajax
  • @author underclounds underclounds@gmail.com
  • / class ajaxOrder { /*
    • @var string 客户姓名
      */
      public $username;
    /**
    • @var string 预留手机
      */
      public $tel;
    /**
    • @var string 预约分类
      */
      public $sorts;
    /**
    • @var string 预留地址
      */
      public $address;
    /**
    • @var int 面积
      */
      public $area;
    /**
    • @var string 预约时间
      */
      public $ordertime;
    /**
    • @var object $dsql 全局数据库操作对象(dede)
      */
      private $dsql;
    /**
    • @var int 错误码
      */
      protected $errcode = 1000;
    /**
    • @var string 提示信息
      */
      protected $errmsg = ‘ok’;
    /**
    • 构造方法
    • ajax constructor.
      */
      public function __construct($dsql)
      {
      $this -> dsql = $dsql;
      if(!empty($_POST[‘username’])) {
      $this -> username = self::filter($_POST[‘username’]);
      }
      if(!empty($_POST[‘tel’])) {
      $this -> tel = self::filter($_POST[‘tel’]);
      }
      if(!empty($_POST[‘sorts’])) {
      $this -> sorts = self::filter($_POST[‘sorts’]);
      }
      if(!empty($_POST[‘address’])) {
      $this -> address = self::filter($_POST[‘address’]);
      }
      if(!empty($_POST[‘area’])) {
      $this -> area = self::filter($_POST[‘area’]);
      }
      if(!empty($_POST[‘ordertime’])) {
      $this -> ordertime = self::filter($_POST[‘ordertime’]);
      }
      }
    /**
    • 检查所有参数
    • @return bool
      */
      public function check()
      {
      if(!$this->checkToken()) return false;
      if(!$this->verifyName($this->username)) return false;
      if(!$this->verifyTel($this->tel)) return false;
      $this -> add();
      return true;
      }
    /**
    • 检查csrf_token是否正确
    • @return bool
      */
      private function checkToken()
      {
      @session_start();
      $sessionId = session_id();
      $token = $_SERVER[‘HTTP_X_CSRF_TOKEN’];
      $cacheToken = GetCache($sessionId,’csrf_token’);
      if(!empty($token) && !empty($cacheToken) && $token === $cacheToken) {
      return true;
      }
      $this -> errcode = 1005;
      $this -> errmsg = ‘非法请求’;
      return false;
      }
    /**
    • 写入预约数据
      */
      private function add()
      {
      $sql = “INSERT INTO #@__diyform1 (id, ifcheck, username, tel, sorts, address, area, ordertime) “;
      $sql .= “VALUES (NULL, 0, ‘$this->username’, ‘$this->tel’, ‘$this->sorts’, ‘$this->address’, ‘$this->area’, ‘$this->ordertime’); “;
      $this -> dsql->ExecuteNoneQuery($sql);
      }
    /**
    • 检验用户名
    • @param $username string 用户名
    • @return bool
      */
      public function verifyName($username)
      {
      if(!empty($username)) {
      return true;
      }
      $this -> errcode = 1001;
      $this -> errmsg = ‘用户名不能为空’;
      return false;
    } /**
    • 检验手机号码
    • @param $tel
    • @return bool
      */
      public function verifyTel($tel)
      {
      if(!empty($tel)) {
      if(!preg_match(‘/^1[345678]\d{9}$/’, $tel)) {
      $this -> errcode = 1003;
      $this -> errmsg = ‘手机号码格式不正确’;
      return false;
      }
      if($this->telExist($tel)) {
      $this -> errcode = 1004;
      $this -> errmsg = ‘手机号码已预约’;
      return false;
      }
      return true;
      }
      $this -> errcode = 1002;
      $this -> errmsg = ‘手机号码不能为空’;
      return false;
      }
    /**
    • 检验手机是否存在
    • @param $tel string 手机号
    • @return bool
      */
      public function telExist($tel)
      {
      $row = $this -> dsql ->GetOne(” SELECT id FROM #@__diyform1 WHERE tel = ‘{$tel}’ “);
      return !empty($row[‘id’]);
      }
    //以下可实现类似方法…….. /**
    • 一般过滤函数 防止注入
    • @param $str string 字符串
    • @return mixed
      */
      public static function filter($str)
      {
      return preg_replace(‘/(delete|insert|select|update|drop|truncate|where)/i’,””, $str);
      }
    public function returnMsg(){
    $errInfo = array(
    ‘errcode’ => $this -> errcode,
    ‘errmsg’ => $this -> errmsg
    );
    return json_encode($errInfo);
    }
    //魔术方法set
    public function __set($name, $value)
    {
    $this -> $name = $value;
    } //魔术方法get
    public function __get($name)
    {
    return $this -> $name;
    }
    }

$ajax = new ajaxOrder($dsql);
$ajax -> check();
echo $ajax -> returnMsg();

前端测试代码

    var token = "{dede:csrftoken exp='10'/}";
    $.ajax({
        url: 'http://localhost/plus/ajaxOrder.php',
        type: 'post',
        headers: {"X-CSRF-TOKEN" : token},
        data: data,
        dataType: 'json',
        success:function (e) {
            console.log(e);
        }
    });

失败返回示例如下:

成功返回示例如下:

注意:笔者使用缓存方式储存csrf_token 以SESSIONID作为识别用户标识,默认十分钟过期。
本文意在使用signature方式校验,故服务端除csrf_token外的校验写法较为简略,读者可自行扩展。

BT宝塔Nginx设置只允许域名访问禁止IP访问 SSL同步设置防源站泄漏

对于用BT宝塔的小伙伴,很多时候建站基本程序都是用NGINX,用的没啥问题,但是大家有没有发现,如果你直接在地址栏上输入IP去访问的话,一般默认会返回一个BT宝塔的默认页面。如果你前面再加上https的话,那么估计就会看到你的网站了。因为宝塔默认没有禁止别人通过IP访问,因此很容易被扫描器扫描到,加上NGINX的通过IP访问HTTPS的话,会自动匹配第一个站点的SSL证书给IP使用,因此会造成IP泄露(证书带域名信息,网上有扫描全网IP并读取SSL证书中域名信息的方法)

那么,怎么设置BT宝塔Nginx设置只允许域名访问,禁止IP访问呢?特别涉及到HTTPS的话,这个源站IP如何防止泄漏呢?虾皮路也捣鼓了一下,分享一下过程。

为了安全起见,接下来需要做两个事情。

1、给IP配置上一张带错误域名的证书,防止泄露你自己的域名

2、禁止直接访问IP,将访问IP的请求,不管是HTTP还是HTTPS全部转错误页  返回状态码444 ERR_EMPTY_RESPONSE

两步其实可以合并成下面步骤操作:

1、在BT宝塔面版上新建站点

首先在宝塔中创建一个默认站点,这里域名随意填写,只要不是你的域名就行。

这里我们可以输入一个 default.com ,或者你也可以输入123.com、456.com等等

BT宝塔Nginx设置只允许域名访问禁止IP访问 SSL同步设置防源站泄漏插图

2、修改默认站点

我们需要将默认的站点改为default.com

BT宝塔Nginx设置只允许域名访问禁止IP访问 SSL同步设置防源站泄漏插图1

3、给默认站点设置证书

给IP配置上一张带错误域名的证书,我们这里利用了CLOUDFLARE来作为错误证书颁发源,利用CF 接入域名,可以颁发15年的仅CF CDN网络体系承认的证书的功能。

大家可以使用我们已经生成的这张证书,反正只要域名不是你真实的域名就行了,提供如下。

公共证书(PEM格式)

-----BEGIN CERTIFICATE-----
MIIDITCCAsagAwIBAgIUTcEWLzynkLCFCoAC1iDH2vG3EkYwCgYIKoZIzj0EAwIw
gY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T
YW4gRnJhbmNpc2NvMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTgwNgYDVQQL
Ey9DbG91ZEZsYXJlIE9yaWdpbiBTU0wgRUNDIENlcnRpZmljYXRlIEF1dGhvcml0
eTAeFw0xOTAxMTMxNDMxMDBaFw0zNDAxMDkxNDMxMDBaMGIxGTAXBgNVBAoTEENs
b3VkRmxhcmUsIEluYy4xHTAbBgNVBAsTFENsb3VkRmxhcmUgT3JpZ2luIENBMSYw
JAYDVQQDEx1DbG91ZEZsYXJlIE9yaWdpbiBDZXJ0aWZpY2F0ZTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABAg/hZ9lDHj/f+0jDRAN23TkNEqIi46mCGnwZVD3glxL
l+a1mpfXLHSEFTipnSyQgmvkPYzQGaEIFD0q6W/ZgMujggEqMIIBJjAOBgNVHQ8B
Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB
/wQCMAAwHQYDVR0OBBYEFCEZF6Eyem01XPbgwr6DXLZV1qsQMB8GA1UdIwQYMBaA
FIUwXTsqcNTt1ZJnB/3rObQaDjinMEQGCCsGAQUFBwEBBDgwNjA0BggrBgEFBQcw
AYYoaHR0cDovL29jc3AuY2xvdWRmbGFyZS5jb20vb3JpZ2luX2VjY19jYTAjBgNV
HREEHDAaggwqLmRuc3BvZC5jb22CCmRuc3BvZC5jb20wPAYDVR0fBDUwMzAxoC+g
LYYraHR0cDovL2NybC5jbG91ZGZsYXJlLmNvbS9vcmlnaW5fZWNjX2NhLmNybDAK
BggqhkjOPQQDAgNJADBGAiEAnrequCk/QZOOrcPH6C3Hgcy4SPNUy5rQtku/aYkj
qQoCIQCN6IyYNiXuwG+8jUgJrveiirBjiz2jXZSTEfVAyibjTg==
-----END CERTIFICATE-----

密钥(KEY)

-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgK0HE3hTJQDg6p/fj
nS92eSuRKZEZ5F4grT6tWFKNYVmhRANCAAQIP4WfZQx4/3/tIw0QDdt05DRKiIuO
pghp8GVQ94JcS5fmtZqX1yx0hBU4qZ0skIJr5D2M0BmhCBQ9Kulv2YDL
-----END PRIVATE KEY-----

把以上两个证书直接复制到默认站点的ssl选项中的其他证书里面,注意不要搞反了。

BT宝塔Nginx设置只允许域名访问禁止IP访问 SSL同步设置防源站泄漏插图2

4、修改站点配置

以上操作完成后,修改默认站点的配置文件

在后面新增一个返回代码:

return 444;

如下图示意

BT宝塔Nginx设置只允许域名访问禁止IP访问 SSL同步设置防源站泄漏插图3

这个时候,无论是通过http://IP访问,还是通过https://IP访问,都将返回无法访问的页面。如果用网上的漏洞扫描程序,扫到的这个IP的证书就是dnspod的了,这样你的IP就不会泄露。