整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          從構(gòu)建分布式秒殺系統(tǒng)聊聊驗證碼

          為了攔截大部分請求,秒殺案例前端引入了驗證碼。淘寶上很多人吐槽,等輸入完秒殺活動結(jié)束了,對,結(jié)束了...... 當(dāng)然了,驗證碼的真正作用是,有效攔截刷單操作,讓羊毛黨空手而歸。

          驗證碼

          如果想學(xué)習(xí)Java工程化、高性能及分布式、深入淺出。微服務(wù)、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群里有阿里大牛直播講解技術(shù),以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費分享給大家。

          那么到底什么是驗證碼呢?驗證碼作為一種人機識別手段,其終極目的,就是區(qū)分正常人和機器的操作。我們常見的互聯(lián)網(wǎng)注冊、登錄、發(fā)帖、領(lǐng)優(yōu)惠券、投票等等應(yīng)用場景,都有被機器刷造成各類損失的風(fēng)險。

          目前常見的驗證碼形式多為圖片驗證碼,即數(shù)字、字母、文字、圖片物體等形式的傳統(tǒng)字符驗證碼。這類驗證碼看似簡單易操作,但實際用戶體驗較差(參見12306網(wǎng)站),且隨著OCR技術(shù)和打碼平臺的利用,圖片比較容易被破解,被破解之后就形同虛設(shè)。

          這里我們使用騰訊的智能人機安全驗證碼,告別傳統(tǒng)驗證碼的單點防御,十道安全柵欄打造立體全面的安全驗證,將黑產(chǎn)拒之門外。

          場景

          下面我們來瞅瞅驗證碼輕松解決了那些場景安全問題:

          • 登錄注冊,為你防護撞庫攻擊、阻止注冊機批量注冊
          • 活動秒殺,有效攔截刷單操作,讓羊毛黨空手而歸
          • 點贊發(fā)帖,有效解決廣告屠版、惡意灌水、刷票問題
          • 數(shù)據(jù)保護,防止自動機、爬蟲盜取網(wǎng)頁內(nèi)容和數(shù)據(jù)

          申請

          申請地址:https://007.qq.com/product.html

          在線體驗:https://007.qq.com/online.html

          只要一個QQ就可以免費申請,對于一般的企業(yè)OA系統(tǒng)或者個人博客網(wǎng)站,驗證碼免費套餐足夠了已經(jīng),具備以下特點:

          • 2000次/小時安全防護
          • 支持免驗證+分級驗證
          • 三分鐘快速接入
          • 全功能配置后臺
          • 支持HTTPS
          • 閾值內(nèi)流量無廣告

          2000次/小時的安全防護,一般很少達到如此效果,當(dāng)然了即時超出閾值,頂多也就是多個廣告而已。

          接入

          快讀接入:https://007.qq.com/quick-start.html

          接入與幫助提供了多種客戶端和服務(wù)端的接入案例,這里我們使用我們秒殺案例中最熟悉的Java語言來接入。

          前端

          引入JS:

           <script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
          

          頁面元素:

          <!--點擊此元素會自動激活驗證碼,不一定是button,其他標(biāo)簽也可以-->
          <!--id : 元素的id(必須)-->
          <!--data-appid : AppID(必須)-->
          <!--data-cbfn : 回調(diào)函數(shù)名(必須)-->
          <!--data-biz-state : 業(yè)務(wù)自定義透傳參數(shù)(可選)-->
          <button id="TencentCaptcha"
           data-appid="*********"
           data-cbfn="callback">驗證</button>
          

          JS回調(diào):

          <script type="text/javascript">
           window.callback = function(res){
           console.log(res)
           // res(未通過驗證)= {ret: 1, ticket: null}
           // res(驗證成功) = {ret: 0, ticket: "String", randstr: "String"}
           if(res.ret === 0){
           startSeckill(res)
           }
           }
           //后臺驗證ticket,并進入秒殺隊列
           function startSeckill(res){
           $.ajax({
           url : "startSeckill",
           type : 'post',
           data : {'ticket' : res.ticket,'randstr':res.randstr},
           success : function(result) {
           //驗證是否通過,提示用戶
           }
           });
           }
          </script>
          

          后端

          @Api(tags = "秒殺商品")
          @RestController
          @RequestMapping("/seckillPage")
          public class SeckillPageController {
           
           @Autowired
           private ActiveMQSender activeMQSender;
           //自定義工具類
           @Autowired
           private HttpClient httpClient;
           //這里自行配置參數(shù)
           @Value("${qq.captcha.url}")
           private String url;
           @Value("${qq.captcha.aid}")
           private String aid;
           @Value("${qq.captcha.AppSecretKey}")
           private String appSecretKey;
           
           @RequestMapping("/startSeckill")
           public Result startSeckill(String ticket,String randstr,HttpServletRequest request) {
           HttpMethod method =HttpMethod.POST;
           MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
           params.add("aid", aid);
           params.add("AppSecretKey", appSecretKey);
           params.add("Ticket", ticket);
           params.add("Randstr", randstr);
           params.add("UserIP", IPUtils.getIpAddr(request));
           String msg = httpClient.client(url,method,params);
           /**
           * response: 1:驗證成功,0:驗證失敗,100:AppSecretKey參數(shù)校驗錯誤[required]
           * evil_level:[0,100],惡意等級[optional]
           * err_msg:驗證錯誤信息[optional]
           */
           //{"response":"1","evil_level":"0","err_msg":"OK"}
           JSONObject json = JSONObject.parseObject(msg);
           String response = (String) json.get("response");
           if("1".equals(response)){
           //進入隊列、假數(shù)據(jù)而已
           Destination destination = new ActiveMQQueue("seckill.queue");
           activeMQSender.sendChannelMess(destination,1000+";"+1);
           return Result.ok();
           }else{
           return Result.error("驗證失敗");
           }
           }
          }
          

          自定義請求工具類 HttpClient:

          如果想學(xué)習(xí)Java工程化、高性能及分布式、深入淺出。微服務(wù)、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群里有阿里大牛直播講解技術(shù),以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費分享給大家。

          @Service
          public class HttpClient {
           public String client(String url, HttpMethod method, MultiValueMap<String, String> params){
           RestTemplate client = new RestTemplate();
           HttpHeaders headers = new HttpHeaders();
           // 請勿輕易改變此提交方式,大部分的情況下,提交方式都是表單提交
           headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
           HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
           // 執(zhí)行HTTP請求
           ResponseEntity<String> response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
           return response.getBody();
           }
          }
          

          獲取IP地址工具類 IPUtils :

          /**
           * IP地址
           */
          public class IPUtils {
           private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
           /**
           * 獲取IP地址
           * 使用Nginx等反向代理軟件, 則不能通過request.getRemoteAddr()獲取IP地址
           * 如果使用了多級反向代理的話,X-Forwarded-For的值并不止一個,而是一串IP地址,X-Forwarded-For中第一個非unknown的有效IP字符串,則為真實IP地址
           */
           public static String getIpAddr(HttpServletRequest request) {
           String ip = null;
           try {
           ip = request.getHeader("x-forwarded-for");
           if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
           ip = request.getHeader("Proxy-Client-IP");
           }
           if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
           ip = request.getHeader("WL-Proxy-Client-IP");
           }
           if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
           ip = request.getHeader("HTTP_CLIENT_IP");
           }
           if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
           ip = request.getHeader("HTTP_X_FORWARDED_FOR");
           }
           if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
           ip = request.getRemoteAddr();
           }
           } catch (Exception e) {
           logger.error("IPUtils ERROR ", e);
           }
           // 使用代理,則獲取第一個IP地址
           if (StringUtils.isEmpty(ip) && ip.length() > 15) {
           if (ip.indexOf(",") > 0) {
           ip = ip.substring(0, ip.indexOf(","));
           }
           }
           return ip;
           }
          }
          

          案例效果圖

          啟動項目訪問:http://localhost:8080/seckill/1000.shtml

          定制接入

          在系統(tǒng)登錄的時候,我們需要先校驗用戶名以及密碼,然后調(diào)用驗證碼操作,這里就需要我們定制接入了。

          <!-- 項目中使用了Vue -->
          <div class="log_btn" @click="login" >登錄</div>
          login: function () {
           //這里校驗用戶名以及密碼
           // 直接生成一個驗證碼對象
           var captcha = new TencentCaptcha('2001344788', function(res) {
           if(res.ret === 0){//回調(diào)成功
           var data = {'username':username,'password':password,'ticket':res.ticket,'randstr':res.randstr}
           $.ajax({
           type: "POST",
           url: "sys/loginCaptcha",
           data: data,
           dataType: "json",
           success: function(result){
           //校驗是否成功
           }
           });
           }
           });
           captcha.show(); // 顯示驗證碼
          },
          

          后臺監(jiān)控

          騰訊后臺還提供了簡單實用的數(shù)據(jù)監(jiān)控,如下:

          歡迎工作一到八年的Java工程師朋友們加入Java高級交流:854630135

          本群提供免費的學(xué)習(xí)指導(dǎo) 架構(gòu)資料 以及免費的解答

          不懂得問題都可以在本群提出來 之后還會有直播平臺和講師直接交流噢

          完小編前段時間發(fā)表的HTML學(xué)習(xí)之后,相信大家對網(wǎng)站建設(shè)與網(wǎng)頁編寫有了一定的初步了解,今天我們來開始介紹層疊樣式表css,css是為HTML頁面的排版美化而設(shè)計的,可以實現(xiàn)html無法設(shè)計的效果,一般是用來配合html來使用的,一般模式:選擇器{屬性:值}即selector{property:value}例如:body{corlor:red;font-size:12px;},他有三種引入方式:行內(nèi)樣式、內(nèi)部樣式表、外部樣式表。

          css三種嵌入方式:

          一、行內(nèi)樣式

          使用style屬性引入CSS樣式。

          示例:

          <h1 style="color:red;">style屬性的應(yīng)用</h1>

          <p style="font-size:14px;color:green;">直接在HTML標(biāo)簽中設(shè)置的樣式</p>

          實際在寫頁面時不提倡使用,在測試的時候可以使用。

          例如:

          <!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title>行內(nèi)樣式</title> </head> <body> <!--使用行內(nèi)樣式引入CSS--> <h1 style="color:red;">Leaping Above The Water</h1> <p style="color:red;font-size:30px;">我是p標(biāo)簽</p> </body> </html>

          二、內(nèi)部樣式表

          在style標(biāo)簽中書寫CSS代碼。style標(biāo)簽寫在head標(biāo)簽中。

          示例:

          <head>

          <style type="text/css">

          h3{

          color:red;

          }

          </style>

          </head>

          例如:<!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title>內(nèi)部樣式表</title> <!--使用內(nèi)部樣式表引入CSS--> <style type="text/css"> div{ background: green; } </style> </head> <body> <div>我是DIV</div> </body> </html>

          三、外部樣式表

          CSS代碼保存在擴展名為.css的樣式表中

          HTML文件引用擴展名為.css的樣式表,有兩種方式:鏈接式、導(dǎo)入式。

          語法:

          1、鏈接式

          <link type="text/css" rel="styleSheet" href="CSS文件路徑" />

          2、導(dǎo)入式

          <style type="text/css">

          @import url("css文件路徑");

          </style>

          例如:<!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title>外部樣式表</title> <!--鏈接式:推薦使用--> <link rel="stylesheet" type="text/css" href="css/style.css" /> <!--導(dǎo)入式--> <style type="text/css"> @import url("css/style.css"); </style> </head> <body> <ol> <li>1111</li> <li>2222</li> </ol> </html>

          行內(nèi)樣式>內(nèi)部樣式>外部樣式(后兩者是就近原則)。

          css注釋格式如下:

          /* 注釋如下*/

          css中的顏色值表示如下:

          可以是直接寫英文單詞,例如藍色盡可以寫blue;還可以寫為十六進制字符,例如#rrggbb\#ffcc00,#rgb如:#fc0十六進制的顏色可以在顏色表中查詢,這里我給大家提供一個,當(dāng)然網(wǎng)上也有很多,大家也可以自己百度一下:

          還有一種顏色的表示方式就是rbg模式,例如:

          rgb(x,x,x) 其中x是一個0-255的整數(shù)值如:rgb(255,204,0)

          rgb(x%,x%,x%) 其中x是一個0-100的整數(shù)值如rgb(100%,80%,0%)

          Css的長度單位:

          相對長度單位:px 像素(Pixel) em 相對于當(dāng)前文本字體尺寸的倍數(shù) % 百分比

          絕對長度單位:in英寸(Inch) pt 點(Point) cm 厘米(Centimeter)mm 毫米(Millimeter)。

          換算比例:1in = 2.54cm = 25.4 mm = 72pt

          Css的七大類選擇器:

          標(biāo)簽選擇器 例如:p{};

          類選擇器 例如.div{};(一個點加命名的類名)

          Id選擇器 例如 #div{};(斜體井號加ID名,ID是不可重復(fù)的,類可以相同)

          通配符選擇器:*{};

          偽類選擇器:

          a:link{}沒有訪問時的鏈接;

          a:visited{}已經(jīng)訪問過時的鏈接;

          a:hove{}鼠標(biāo)滑過時的鏈接;

          a:active{}已經(jīng)選中的鏈接;

          :first-child{}為第一個字符設(shè)置樣式;

          :last-child{}為最后一個字符設(shè)置樣式;

          :nth-child(){}可以為指定字符設(shè)置樣式

          派生選擇器(后代選擇器、子元素選擇器和相鄰兄弟選擇器):

          后代選擇器: 以空格分隔

          div ul li {color:#0099cc;}

          子元素選擇器: 以>分隔

          div >ul li

          相鄰兄弟選擇器: 以+分隔

          div + div ul li

          最后一個就是組合選擇器,以逗號隔開

          h1, h2, h3, h4, h5, h6 { color: green }

          好了,css基礎(chǔ)就給大家介紹到這里,有什么不懂得地方可以給小編留言,如果您有什么好的建議也可以關(guān)注小編,我們共同學(xué)習(xí),共同討論,共同進步,接下來我們會介紹下css的屬性,敬請期待吧

          果想開發(fā)一個網(wǎng)站,除了要精通后端開發(fā)語言(如:php)外,還要精通HTML代碼。那么,什么是HTML呢?HTML是一種超文本標(biāo)記語言,它包含有眾多的標(biāo)簽,我們可以通過這些標(biāo)簽,把不同的internet資源(如:文字、圖片、視頻、音頻、表單等等)整合在一個統(tǒng)一的文檔中,這就形成了我們可以看得見的網(wǎng)頁。那么,HTML都有哪些常用的標(biāo)簽?zāi)兀?/p>

          一、文檔類型聲明。

          html5文檔類型聲明:<!doctype html>

          html4文檔類型聲明:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

          二、html主標(biāo)簽。

          這個標(biāo)簽是html最外層的標(biāo)簽,所有其它的HTML標(biāo)簽都要放在這個標(biāo)簽的內(nèi)部。

          <html>

          <head></head>

          <body></body>

          </html>

          三、雙標(biāo)簽和單標(biāo)簽。

          在HTML標(biāo)簽中,有的標(biāo)簽是成雙成對的,如:<html></html>(如下圖);而有的標(biāo)簽是單個的,如:<hr>橫線標(biāo)簽。

          四、head頭部標(biāo)簽。

          head頭部有以下幾種常用標(biāo)簽:

          meta:主要提供有關(guān)頁面的元信息。

          link:用來定義文檔與外部資源的關(guān)系,最常用的是調(diào)用CSS樣式文件。

          title:頁面標(biāo)題的標(biāo)簽。

          script:用來調(diào)用JS文件或JS代碼。當(dāng)然,script標(biāo)簽也可以在body主體中使用。

          五、body主體標(biāo)簽。

          1、塊級標(biāo)簽。

          塊級標(biāo)簽的特性是:獨自占有一行;標(biāo)簽的高與寬、邊距可以修改;沒有設(shè)置寬與高時,默認繼承父標(biāo)簽。例如:


          <div>div1</div>

          <div>div2</div>

          <style>

          .aa1{ border:1px solid #000; width:150px; height:100px; margin:30px; }

          .aa2{ border:1px solid #000; width:150px; height:100px; margin:30px; }

          </style>


          前端頁面顯示的效果如下圖:

          常用的塊級標(biāo)簽有:div、h1、h2、h3、h4、h5、h6、hr、menu、ul、ol、li、dl、dt、dd、table、p、form 。

          2、內(nèi)聯(lián)標(biāo)簽。

          內(nèi)聯(lián)標(biāo)簽與塊級標(biāo)簽不同,它不能獨自占有一行,會與其它內(nèi)聯(lián)標(biāo)簽在同一樣展示;內(nèi)聯(lián)標(biāo)簽的高與寬、上下邊距是不能修改的,它里面的文字或圖片有多高,它就是多高。例如如下代碼:


          <style>

          .aa1{ border:1px solid #000; width:150px; height:100px; margin:30px; }

          .aa2{ border:1px solid #000; width:150px; height:100px; margin:30px; }

          </style>

          <span>span1</span>

          <span>span2</span>


          CSS樣式代碼跟塊級標(biāo)簽的例子是一樣的,而顯示的效果就不一樣了,寬與高、上下邊距沒有效果。如下圖:

          常用的內(nèi)聯(lián)標(biāo)簽有:span、a、b、strong、i、em 。

          3、內(nèi)聯(lián)塊級標(biāo)簽。

          內(nèi)聯(lián)塊級標(biāo)簽,既有一些內(nèi)聯(lián)標(biāo)簽的特性,也有一些塊級標(biāo)簽的特點:它不能獨自占有一行,但是可以修改它的寬度和高度。例如下面這段代碼:


          <style>

          .aa1{ border:1px solid #000; width:150px; height:100px; margin:30px; }

          .aa2{ border:1px solid #000; width:150px; height:100px; margin:30px; }

          </style>

          <img src="w5.jpg" alt="">

          <img src="w5.jpg" alt="">


          CSS樣式代碼跟塊級標(biāo)簽的那個例子仍然是一樣的,圖片的寬和高、上下邊距修改成功,而2個圖片不能獨自占有一行,而是在同一行。如下圖:

          常用的內(nèi)聯(lián)塊級標(biāo)簽有:img、input、textarea。

          4、區(qū)域標(biāo)簽。

          所謂區(qū)域標(biāo)簽,就是主要用來劃分布局頁面區(qū)域的。如:頭部、主體內(nèi)容、側(cè)邊欄、底部。這樣劃分的好處是:讓頁面布局更加清晰明了。

          常用的區(qū)域標(biāo)簽有:header(頭部)、footer(底部)、nav(導(dǎo)航)、aside(側(cè)邊欄)、section(主體)、article(獨立內(nèi)容)。

          5、表單標(biāo)簽。

          這個表單標(biāo)簽我們也是會經(jīng)常用到的,如:登錄網(wǎng)站的時候、提交數(shù)據(jù)的時候。如下圖的評論表單:

          ?表單常用的標(biāo)簽有:form、input、select、option、textarea 。

          以上就是我們開發(fā)網(wǎng)頁時,會常用到的HTML標(biāo)簽。當(dāng)然,HTML標(biāo)簽遠不止這些,尤其是html5出來后,新增了許多的新標(biāo)簽。但是,有些標(biāo)簽在我們開發(fā)中很少用到,所以,這里就沒有做相應(yīng)的介紹。


          主站蜘蛛池模板: 精品人妻无码一区二区三区蜜桃一| 国产美女在线一区二区三区| 国产成人无码一区二区三区在线 | 精品一区二区三区在线观看视频 | 国产乱码精品一区二区三区四川| 久久se精品一区二区影院| 国产亚洲福利精品一区| 国产精品亚洲一区二区三区久久| 国产内射在线激情一区| 国产视频一区二区在线观看| 少妇无码一区二区二三区| 视频一区视频二区在线观看| 国产精品视频一区二区三区经| 亚洲无人区一区二区三区| 久久免费区一区二区三波多野| 亚洲一区中文字幕久久| 制服丝袜一区二区三区| 日韩久久精品一区二区三区| 中文字幕日韩人妻不卡一区| 国产一区二区三区亚洲综合 | 3d动漫精品啪啪一区二区中文| 亚洲国产精品一区二区三区久久| 日韩在线一区二区| 日本一区二区不卡在线| 99热门精品一区二区三区无码 | 中文无码一区二区不卡αv | 精品视频一区二区三区| 国产在线一区视频| 亚洲av色香蕉一区二区三区蜜桃| 久久er99热精品一区二区| 精品国产一区二区三区免费 | 制服中文字幕一区二区| 一区二区三区免费高清视频| 视频一区二区在线观看| 日本一区二区三区在线观看视频| 无码人妻精品一区二区三区9厂 | 夜夜精品无码一区二区三区| 国产成人无码精品一区不卡| 国产精品成人99一区无码| 国产一区二区三区在线观看影院| 精品免费国产一区二区三区 |