最近做了一個小需求,結果坑特別多。。。。。
需求是這樣的,要給公司內部做一個微信公眾號廣告投票系統,整個項目就不多贅述了,有個小功能,要求是這樣的:
點擊某條記錄后的“投票”按鈕,在當前頁面彈出彈窗顯示文章內容(讀取文章url,需要正確展示文字、圖片、排版等),保持3分鍾,這期間在當前頁面上不可進行任何操作,不可投票也不可關閉文章。3分鍾后,文章下方的投票區域可用,點擊“提交”按鈕時,校驗所有項目是否都已選擇,如果沒有,則彈窗提示。提交完成后,狀態更改為“已投票”(只是針對該用戶,不針對該公眾號信息的記錄)
這個小功能很簡單,結果遇到了很多坑點
首先是微信公眾號地址跨域了(第一個問題。。。。。)
解決這個問題,使用了ajax解決的,使用了一個第三方的跨域api代碼如下:
//解決微信公眾號文章的跨域問題 $.ajaxPrefilter( function (options) { if (options.crossDomain && jQuery.support.cors) { var http = (window.location.protocol === 'http:' ? 'http:' : 'https:'); options.url = http + '//cors-anywhere.herokuapp.com/' + options.url; } }); $.get( articleUrl, function (response) { var innerHtml = response; $('.article-box').html('<div class="article-code-box">' + innerHtml + '</div>')//解決微信公眾號文章圖片的防盜鏈問題 innerHtml = innerHtml.replace(/data-src/g, "src") innerHtml = innerHtml.replace(/(wx_fmt=gif)|(wx_fmt=png)|(wx_fmt=jpg)|(wx_fmt=jpeg)/g, "") $('.article-box').html('<div>' + innerHtml + '</div>') } );
好了,解決了跨域,使用iframe的時候加載不進去,只能當做div元素嵌套在前端頁面上(第二個問題。。。。。)
解決了這個之后,又有新問題微信的公眾號文章里的圖片,微信加了防盜鏈,會顯示
然后查了一下發現,是微信給公眾號文章加了防盜鏈,網上有幾種解決辦法,都比較復雜,經過觀察發現,無法正常顯示是因為,將圖片的真正地址在data-src里,並且在圖片的地址后面拼了wx_fmt這個參數,於是是這樣解決的,將data-src放入src里,將圖片后綴去掉,代碼如下:
//解決微信公眾號文章圖片的防盜鏈問題 innerHtml = innerHtml.replace(/data-src/g, "src") innerHtml = innerHtml.replace(/(wx_fmt=gif)|(wx_fmt=png)|(wx_fmt=jpg)|(wx_fmt=jpeg)/g, "")
之后,發現還有坑。。。。。(第三個問題。。。。)發現有的時候,會返回“訪問過於頻繁,請用微信掃描二維碼進行訪問”然后一個二維碼一句話,document.write
把我的整個頁面給覆蓋掉了,然后和產品溝通了一下,產品說反正是讓投票人看到文章就可以,通過二維碼掃描也可以。。
於是我直接將這個頁面放在了我的文章div里
innerHtml = innerHtml.replace(/document.write/g, "$('.article-code-box').html")
//解決微信公眾號文章的跨域問題 $.ajaxPrefilter( function (options) { if (options.crossDomain && jQuery.support.cors) { var http = (window.location.protocol === 'http:' ? 'http:' : 'https:'); options.url = http + '//cors-anywhere.herokuapp.com/' + options.url; } }); $.get( articleUrl, function (response) { var innerHtml = response; var isChecked = new RegExp("訪問過於頻繁,請用微信掃描二維碼進行訪問"); if(isChecked.test(innerHtml)){ //解決請求被微信攔截時的二維碼顯示 innerHtml = innerHtml.replace(/document.write/g, "$('.article-code-box').html") $('.article-box').html('<div class="article-code-box">' + innerHtml + '</div>') }else{ //解決微信公眾號文章圖片的防盜鏈問題 innerHtml = innerHtml.replace(/data-src/g, "src") innerHtml = innerHtml.replace(/(wx_fmt=gif)|(wx_fmt=png)|(wx_fmt=jpg)|(wx_fmt=jpeg)/g, "") $('.article-box').html('<div>' + innerHtml + '</div>') $('#js_pc_qr_code').remove() } } );
整個頁面的demo如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="referrer" content="never"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>投票</title> </head> <style> p{margin: 0} .article-loading{ width: 100%; height:100%; display: flex; justify-content: center; align-items: center; } .article-loading div{ width: 4px; height: 10px; background-color: #2894FF; display: inline-block; margin-left:6px; animation:load2 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite; -webkit-animation:load2 0.5s cubic-bezier(0.77, 0.47, 0.64, 0.28) alternate infinite; } .article-loading div:nth-child(1){ animation-delay: -0.5s; } .article-loading div:nth-child(2){ animation-delay: -0.4s; } .article-loading div:nth-child(3){ animation-delay: -0.3s; } .article-loading div:nth-child(4){ animation-delay: -0.2s; } .article-loading div:nth-child(5){ animation-delay: -0.1s; } @keyframes load2{ from{transform:scaleY(1);} to{transform:scaleY(3);} } @-webkit-keyframes load2{ from{transform:scaleY(1);} to{transform:scaleY(3);} } .vote-out-box{ /* display: flex; */ display: none; position: fixed; top: 0; right: 0; bottom: 0; left: 0; height: 100%; width: 100%; z-index: 1000; background-color: rgba(0, 0, 0, 0.65); justify-content: center; align-items: center; } .vote-con-box{ display: flex; justify-content: center; align-items: center; flex-direction: column; width: 50%; height: 95%; background-color: #fff; background-clip: padding-box; border: 0; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: 5px; z-index: 2000; } .article-box{ width: 100%; flex:1; text-align: center; position: relative; overflow-y: scroll; overflow-x: hidden; } .article-code-box{ width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .plase-finash-vote-box{ width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .plase-finash-vote{ width: 100%; height: 50px; line-height: 50px; font-size: 20px; text-align: center; } .vote-list-box{ width: 80%; height: 104px; margin: 10px auto 5px; border: 1px solid #333333; overflow: hidden; } .vote-list-box .vote-list-con{ border-top: 1px solid #333333; height: 20px; display: flex; } .vote-list-box .vote-list-first{ border-top: none; } .vote-left-menu{ width: 45%; line-height: 20px; border-right: 1px solid #333333; padding:0 5px; color: #333333; } .vote-right-select{ display: flex; justify-content: center; align-items: center; } .put-Vote{ width: 100px; height: 30px; background: #2894FF; line-height: 30px; color: #ffffff; border-radius: 4px; text-align: center; margin-bottom: 5px; cursor: pointer; } .get-vote{ display: block!important; } /*訪問過於頻繁時二維碼的大小*/ .qrcheck_img{ width: 300px;!important; height: 300px;!important; } .goto-vote{ width: 100px; height: 30px; margin: 100px auto; background: #2894FF; line-height: 30px; text-align: center; border-radius: 4px; color: #ffffff; } </style> <body> <div class='goto-vote'>去投票</div> <!-- 投票彈框 --> <div class="vote-out-box"> <ul class="vote-con-box"> <div class="article-box"> <div class="article-loading"> <div></div> <div></div> <div></div> <div></div> <div></div> </div> </div> <div class="vote-list-box"> <form class="get-vote"> <div class="vote-list-con vote-list-first"> <p class="vote-left-menu">文章標題吸引人</p> <div class="vote-right-select"> <input type="radio" name="radioOne" value=1>1分 <input type="radio" name="radioOne" value=2>2分 <input type="radio" name="radioOne" value=3>3分 <input type="radio" name="radioOne" value=4>4分 <input type="radio" name="radioOne" value=5>5分 </div> </div> <div class="vote-list-con"> <p class="vote-left-menu">文章標題和內容匹配</p> <div class="vote-right-select"> <input type="radio" name="radioTwo" value=1>1分 <input type="radio" name="radioTwo" value=2>2分 <input type="radio" name="radioTwo" value=3>3分 <input type="radio" name="radioTwo" value=4>4分 <input type="radio" name="radioTwo" value=5>5分 </div> </div> <div class="vote-list-con"> <p class="vote-left-menu">看完文章想要轉發</p> <div class="vote-right-select"> <input type="radio" name="radioThree" value=1>1分 <input type="radio" name="radioThree" value=2>2分 <input type="radio" name="radioThree" value=3>3分 <input type="radio" name="radioThree" value=4>4分 <input type="radio" name="radioThree" value=5>5分 </div> </div> <div class="vote-list-con"> <p class="vote-left-menu">看完文章想要點贊</p> <div class="vote-right-select"> <input type="radio" name="radioFour" value=1>1分 <input type="radio" name="radioFour" value=2>2分 <input type="radio" name="radioFour" value=3>3分 <input type="radio" name="radioFour" value=4>4分 <input type="radio" name="radioFour" value=5>5分 </div> </div> <div class="vote-list-con"> <p class="vote-left-menu">總的來說,覺得這篇文章好看</p> <div class="vote-right-select"> <input type="radio" name="radioFive" value=1>1分 <input type="radio" name="radioFive" value=2>2分 <input type="radio" name="radioFive" value=3>3分 <input type="radio" name="radioFive" value=4>4分 <input type="radio" name="radioFive" value=5>5分 </div> </div> </form> </div> <div class="put-Vote">提交投票</div> </div> </div> </body> </html> <script type="text/javascript" src="https://cdn.11bee.com/scripts/static/js/jquery-3.0.0.min.js"></script> <script type="text/javascript"> var voteContentId=[ {normName:'文章標題吸引人'}, {normName:'文章標題和內容匹配'}, {normName:'看完文章想要轉發'}, {normName:'看完文章想要點贊'}, {normName:'總的來說,覺得這篇文章好看'}, ] //文章加載完成3分鍾后需要進行的操作 function isUseable(cbk){ timer=setTimeout(function () { $('.article-box').html('<div class="plase-finash-vote-box"><p class="plase-finash-vote">請完成投票</p></div>') $('.vote-list-box input').removeAttr("disabled"); $('.put-Vote').off() $('.put-Vote').on('click',function(){ var selectValue = $(".get-vote").serializeArray(); //3分鍾后投票選項是否全部完成 if(selectValue.length<5){ alert('請完成所有投票選項') }else{ for(var i=0;i<selectValue.length;i++){ voteContentId[i].id=selectValue[i].name voteContentId[i].score=selectValue[i].value } clearTimeout(timer); $('.vote-out-box').css('display','none'); // 提交按鈕,提交數據 $.ajax({ type: "post", url: "/admin/serving/addVoteResult", data: { voteNorms: customerUserName, voteContentId: voteContentId }, dataType: "json", async: false, success: function (data) { console.log(data) cbk && cbk } }); } }) }, 180); } //渲染函數 function voteRender(articleUrl,cbk){ isUseable(cbk) $('.vote-list-box input').attr("disabled","disabled"); // 未到3分鍾時彈窗提示 $('.put-Vote').on('click',function(){ alert('您有3分鍾的時間閱讀文章,請先閱讀文章') }) //解決微信公眾號文章的跨域問題 $.ajaxPrefilter( function (options) { if (options.crossDomain && jQuery.support.cors) { var http = (window.location.protocol === 'http:' ? 'http:' : 'https:'); options.url = http + '//cors-anywhere.herokuapp.com/' + options.url; } }); $.get( articleUrl, function (response) { var innerHtml = response; var isChecked = new RegExp("訪問過於頻繁,請用微信掃描二維碼進行訪問"); if(isChecked.test(innerHtml)){ //解決請求被微信攔截時的二維碼顯示 innerHtml = innerHtml.replace(/document.write/g, "$('.article-code-box').html") $('.article-box').html('<div class="article-code-box">' + innerHtml + '</div>') }else{ //解決微信公眾號文章圖片的防盜鏈問題 innerHtml = innerHtml.replace(/data-src/g, "src") innerHtml = innerHtml.replace(/(wx_fmt=gif)|(wx_fmt=png)|(wx_fmt=jpg)|(wx_fmt=jpeg)/g, "") $('.article-box').html('<div>' + innerHtml + '</div>') $('#js_pc_qr_code').remove() } } ); } //文章的URL var articleUrl='https://mp.weixin.qq.com/s?__biz=MzU4MTcyMTM2Mw==&mid=2247485252&idx=1&sn=a760748c5b174ee96c92edc779a5528b&chksm=fd420b38ca35822e2e77f7c7d6f11b5013b54606fcbacbe42abf0ec6cd0b93596f0e2b88131a&scene=0&xtrack=1&key=7f1d049d633b1d67ab8c356a0a47bd7d5e3c526a1e4f6219a1a788ac49e4cc710e2fb869c6eea5600601c386667b75385600c7bf33b4944ae03c7480fd9cd3e7ba310080b1f664396993c4364cc9f804&ascene=1&uin=OTM3NDg5NDQx&devicetype=Windows+10&version=62060833&lang=zh_CN&pass_ticket=CH%2Fn62cerUJDtvxUNSrMPARiIA4WocXX89L%2FzA9w5wKBw8lMxvZTzO1D00A4keTT' //點擊提交按鈕之后的函數,自定義函數 function cbk(){ } $('.goto-vote').on('click',function(){ $('.vote-out-box').css('display','flex'); voteRender(articleUrl,cbk) }) </script>
一個簡單的小功能做的我好惡心。。。。。。