2018年10月29日 星期一

Qnap 編輯crontab檔案 設定排程

紀錄一下qnap 編輯排程檔案crontab的方式

Step 1.使用ssh連線:
(需在qnap的「網路&檔案服務」內勾選允許ssh連線)

連線方式:開啟電腦終端機軟體以admin帳號連線qnap主機的server
ssh admin@xxx.xxx.xxx.xxx  <--後面xxx是ip
按下enter後接著輸入管理者密碼

Step 2.進入crontab編輯指令
一般linux版本會使用crontab -e進入編輯crontab,但是以這種方式qnap再主機重啟的時候會覆蓋寫好的配置,所以在qnap上應該輸入下列指令進入vi編輯模式
vi /etc/config/crontab

Step 3. vi編輯模式
一開始進入的時候只是vi的一般模式(只能上下左右移動),按一下鍵盤的i鍵,即可進入輸入模式(下方會出現--insert--字樣),這樣才可以開始輸入打字

Step 4. 範例:定時執行php程式
這次要紀錄的是在qnap上設定crontab 定期執行qnap虛擬主機網頁上的某個php檔案,
在步驟3進入編輯後,新增一行下方的cron job設定:

以下是設定每五分鐘執行一次 xxx.com.tw 網址下的xxx.php程式

*/5 * * * * /usr/bin/wget http://xxx.com.tw/xxx.php

※因為自己的虛擬主機有設定網址轉址,所以直接輸入網址,這部分如果直接執行qnap主機的內部位置,譬如 /share/CACHEDEV1_DATA/web/xxx/xxx.php 無法順利執行(這部分還沒研究是什麼原因),另外只有寫http網址也無法解析php檔案,所以前面加上/usr/bin/wget,以wget來執行。

Step 5. 儲存離開vim編輯模式
完成步驟4的編輯後,按一下esc跳離vi編輯模式,再按一下鍵盤的 : 然後按下enter鍵
就會跳離編輯區,在左下方出現:符號,接著輸入wq (儲存後離開)按下enter,便可儲存跳離vi編輯器。(如果想離開但是不儲存,則輸入q!)

Step 6. 重新啟動crontab
輸入以下指令重新啟動crontab
crontab /etc/config/crontab && /etc/init.d/crond.sh restart

Step 7. 檢查crontab
重新啟動crontab後,可輸入 crontab -l (小寫的L)
檢查剛剛新增的cron工作

參考網址:
https://wiki.qnap.com/wiki/Add_items_to_crontab
https://forum.qnap.com/viewtopic.php?t=14673
https://forum.qnap.com/viewtopic.php?f=32&t=40809

2018年9月7日 星期五

修改並自定義 mac coding軟體sublime text 及 coda 2的emmet外掛

emmet for coda版本的外掛能夠自己定義預設的一些文字
 譬如輸入!按下Ctrl+e 通常會出現:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>

</body>
</html>

雖然很方便 但是有些地方還要自己修改,譬如上面的en
希望能夠ctrl+e後可以自動變成慣用或常用的語言(如:tw)

這時候可以透過修改emmet的snippets.json檔案來達成

原本coda內的emmet這個snippets.json是存在如下圖的位置



但是emmet的設定內可以自己在自訂的位置新增一個snippets.json檔案,
並且在裡面自己定義一些內容,步驟如下:

Step 1.
以lang舉例:
寫了lang的自定義如下,把原本的"lang":"en"改為"lang":"tw"(寫法可以參考上方原檔案內的方式),寫好後存成snippets.json放在自己想要的資料夾內。



Step 2.
在coda軟體上方選單列點選Emmet/Preferences,進入Emmet的設定



Step 3.
點擊Browser選取自己剛剛存的snippets.json所在的資料夾位置,
然後關閉這個設定視窗




之後只要重新啟動coda,新開一個檔案輸入! 然後按下ctrl+e
接者就會看到新的設定生效囉!!




PS. sublime text 基本上也是一樣的做法
在Package Settings內把emmet的Settings - Default所有內容copy一份
然後貼到Settings - Users內,
然後把裡面的"extensions_path": "~/emmet" 這一行
後面的emmet是預設的路徑,
把它改到snippets.json的存放資料夾即可




2018年8月9日 星期四

手機版網頁css bakcground fixed無法作用的問題

要在body設定background的背景圖為fixed
但是在手機版(ios)觀看會沒有作用,背景圖還是會跑

網路上搜尋到效果比較好的解決方式如下,做一下紀錄:
body:before {
  content: "";
  display: block;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: -10;
  background: url(../images/starBack.jpg) no-repeat center center;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
  padding-bottom: 20%;
}
請注意z-index值為-10。
html根元素默認z-index為0.
此值必須是最小z-index才能將其為背景。

2018年8月2日 星期四

網站功能在inAppBrowser(line / facebook)內無法使用的問題

在使用www.addevent.com 的訂閱行事曆服務時
發現如果是用手機在line裡面點擊活動網址的連結,
那麼點擊裡面的「加入行事曆」按鈕功能會沒有反應
(目前是在iphone上行事曆的問題,若經由FB點擊連結可以正常操作)

原因是因為Line會開啟自身App內的瀏覽器。
因為這類的 inAppBrowser/UIWebView 瀏覽器跟一般手機內的瀏覽器APP不同
會導致一些JS功能失效。

下方搜尋到的文章有比較清楚的介紹
https://blog.user.today/inapp-browser-webview-problem/

先做一下紀錄。

iphone的ios取消訂閱行事曆

iphone訂閱行事曆後,想要刪除該行事曆
進的行事曆App 或是ios「設定」內的「行事曆」選項,
只能看到「已訂閱行事曆」裡面的項目,
但是翻來翻去找不到刪除該行事曆的選項或按鈕。

浪費了一段時間翻找,才發現是藏在
「設定」/「帳號與密碼」裡面  (87~ 藏在這裡幹嘛!!)



點進帳號密碼後,會有一個「已訂閱的行事曆」選項。
進入後點擊要刪除的行事曆,然後按最下面的「刪除帳號」,就可以刪除了

2018年7月25日 星期三

快速清除table表格或div內的所有屬性,以便取得乾淨的html碼

這篇主要是備註,有時從客戶端取得的製作文件 如:表格、設定過格式的ppt或doc文件檔案等等,需要把內容移植成html格式,使用以下的方法可快速得到乾淨的html檔案

以下以ppt檔案內的表格為例,假設ppt檔案內有一個複雜的表格要轉為html碼

1.開啟ppt檔案,轉存為pdf

2.使用acrobat開啟該pdf,然後轉存為html檔案

/* 以上兩個步驟主要是要把ppt檔案的表格轉存為html檔案,使用別的方式也可以 */

3.開啟html檔案,通常會看到html碼內已經被設定了一堆密密麻麻的屬性,此時先大概刪除掉不需要的部分,取得單純的<table></table> 這一段內的html碼

4.在該文件加上html , head, body,.....  等等網頁tag,另外也順便掛上jquery引用路徑

5.在最後加上下面的java script

<script>
 $(function(){     $('*').removeAttr('style');   //移除文件內的所有style 屬性     $('*').removeAttr('class');   //移除文件內的所有class 屬性     $('*').removeAttr('bgcolor');    //移除文件內的所有bgcolor 屬性     $('* p').contents().unwrap();   //把所有用<p>包起來的內容解開(移除<p></p>)   }) </script>

/* 按照上面的邏輯可以自己加上想要移除的tag或屬性 */

6.使用瀏覽器瀏覽該網頁檔案

7.使用chrome的 /檢視/開發人員選項/開發人員工具 檢視,從檢視碼內就可以把去掉tag及屬性的內碼copy出來


powerpoint 2010 把ppt存成網頁

在powerpoint 2010 的功能列選項內沒有「另存成網頁」這個選擇,必須另外處理,步驟如下:

1.開啟ppt檔案,按下alt+F11 開啟VBA,然後按下Ctrl+G (windows) 或 ^⌘G (Mac) 顯示立即視窗(如下圖)



2.在立即視窗內輸入
ActivePresentation.SaveAs "C:/test.htm", ppSaveAsHTML, msoFalse
(mac檔名處若不加上路徑直接輸入 "test.htm" 則檔案會存到「文件」資料夾內)。
然後按下Enter,即可在指定路徑下存成test.htm檔案

2018年7月23日 星期一

用photoshop 壓縮優化png圖檔,減少圖檔大小 避免造成網頁loading過重

做網頁儲存png圖檔時,常常檔案很大會造成網頁loading較重
可使用photohsop內的 影像/調整/色調分離 來降低圖檔內的色階
然後再轉存,進而減少檔案的大小。

2018年7月20日 星期五

jquery 算出隨機整數字

var randomNum = Math.floor(Math.random() * customVal);
//customVal 可以是自訂的參數,譬如以視窗或指定div的高或寬

2018年7月10日 星期二

jquery引用網址

jquery官方提供的網址

<script src='//code.jquery.com/jquery-2.1.4.min.js'></script>


google提供的網址

<script src='//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'></script>

注意:
Google CDN網址雖然是比較好的選擇,但為了避免被大陸地區google的服務會有異常,建議使用jquery官方提供的引用網址
後方的數字可更改以符合最新版次,jquery版本資訊可見這裡



2018年7月7日 星期六

Android studio使用emulate Android模擬器時出現device still connecting bug臭蟲的修正方式

狀況:
終端機使用$ cordova emulate android指令時,無法正常開啟並執行Android studio的模擬器

錯誤碼:

(node:1225) UnhandledPromiseRejectionWarning: CordovaError: Failed to execute shell command "getprop,dev.bootcomplete"" on device: Error: adb: Command failed with exit code 1 Error output:
error: device still connecting

修正方式:
Step1.
開啟電腦資料夾至APP專案內下面這個位置的emulator.js檔案
yourAppName/platforms/android/cordova/lib/emulator.js

Step2.
以編碼軟體開啟emulator.js檔案,並且找到下面語法
if ((error && error.message &&
    (error.message.indexOf('not found') > -1)) ||
    (error.message.indexOf('device offline') > -1))

Step3.
把上面這段語法改為如下:(紅色字標註是新增的部分)
if ((error && error.message &&
    (error.message.indexOf('not found') > -1)) ||
    (error.message.indexOf('device offline') > -1) ||
    (error.message.indexOf('device still connecting') > -1))

Step4.
修改完並且儲存後,再次於終端機執行模擬指令
$ cordova emulate android
即可順利開啟模擬器

Reference:
  1. https://stackoverflow.com/questions/50935337/failed-to-execute-shell-command-getprop-dev-bootcomplete-on-device-error-for
  2. https://issues.apache.org/jira/browse/CB-14165
  3. https://github.com/apache/cordova-android/pull/457/files


2018年6月28日 星期四

讓瀏覽器或手機版瀏覽器強制更新(force reload)網頁的css,以讀取最新的css樣式修改

常常在線上維護網頁時發現css樣式表裡面已經做了修改
但是從瀏覽器看,還是讀到舊的。

電腦上的瀏覽器(如chrome)還能以開發者模式來強制網頁更新讀取新檔,
但是在手機版的瀏覽器就只能刪除cookie重來,不但操作步驟多麻煩,
而且也無法每次更新後都提醒網頁的瀏覽者去清cookie。
讓網頁瀏覽者可能無法即時看到網頁的樣式更新

只要在style連結的css檔案路徑後方加上變數即可使瀏覽器強制更新
以下紀錄兩個根據不同狀況可以使用的簡單方法

1.在css連結的後方加上任意的變數(v是變數名可任意取,後面2.0是隨意的數字)
如:<link  rel="stylesheet" type="text/css" href="./css/style.css?v=2.0">

2.在css連結後方加上時間參數(適合以php檔案做開發時測試用)
上面第一種方式,如果在開發時,每做一次樣式修改就要改一下變數的數字太過費工。
如果是以php寫網頁,那麼可以在css連結後方帶一個time()取得現在的時間。

如:<link  rel="stylesheet" type="text/css" href="./css/style.css?v=<?=time();?>">

因為每一次修改或重整網頁都會有時間差,所以經由time()函式取得當下操作的時間,
那麼v變數就會不斷改變。

第二種方式適合開發時測試使用,完成上線後還是以第一種方式為主,這樣瀏覽者才不用每次重新整理網頁都要讀一次css檔


2018年5月11日 星期五

CSS 上下左右全置中

CSS 上下左右全置中
2021 ==== 更新
使用flex 可以更快處理上下左右全置中
ex:
html,body{
 padding:0;
 margin: 0;
 width: 100%;
 height: 100%;
}

//粉紅色大底
.parents{  
width: 100%;
height: 100%;
background:pink;
display: flex;
}

//要置中的藍色區塊
.child{
margin: auto;
width: 500px;
height: 500px;
background: blue;
}

結果如下












 ==CSS2通用版=============
.box{
width:220px;

height:200px;
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}

==CSS3加強版=============
.box{
width:220px;
height:200px;
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
}
若要製作lighBox效果的填入畫面

若要淡黑背景中間的區塊一直保持在畫面中,如下方html
<div id='wrapper'> <-- 淡黑背景
   <div id='content'> <-- 要置中的內容
        <form> .... </form>
   </div>
</div>

若內容高於視窗高度時,在滾動滑鼠捲軸時會產生
置中的內容跟著往上跑或不會出現在畫面中央的問題
這時候可把 content 的position設為fixed即可,
不管滑鼠如何滾動 該區塊都會保持在畫面中央



2018年4月19日 星期四

ajax post 資料不使用form格式,直接用id或class讀取input的vlaue值post

 html的部分                   

<input type="radio" name"data1" value="1">
<input type="text" name"data2" value="data2的資料">
<textarea rows="10" cols="80" name="data3" ></textarea>

 javascript的部分                   

function postData(){
if(confirm('確定要新增此則資料?')){
var dataValues={
data1:$('input[name=data1]').val(), data2:$('input[name= data2]').val(), data3:$('textarea[name= data3]').val()
}    //也可以使用輸入欄位的id或classsName帶入資料     $.ajax({         url:'addData.php',         type: 'POST',         data: dataValues,         async: false,         success: function (msg) {          alert(msg)          },         cache: false     });
    return false;
}else{    return false; }

}

 php的部分                   

然後addData.php頁面就可接收
$_POST['data1']
$_POST['data2']
$_POST['data3']
這三個值 

2018年4月9日 星期一

safari新版(11.1或之前不知幾版之後)的問題,呼叫ajax時,type=file的input物件若為空,會顯示failed to load resource:要求逾時的錯誤

safari新版(11.1或之前不知幾版之後)的問題,

呼叫ajax時form data型態
若form內有type=file的input物件是空值時,
那麼submit之後,會顯示failed to load resource:要求逾時  的錯誤

在chrome上功能可正常運作 ,只有safari會顯示此錯誤

目前解決方式:
在送出ajax前,若form內的檔案上傳(input type=file)是空的,也就是沒有檔案需要上傳
那麼,就把這個input刪除

$("input[type=file]").each(function() {
    if($(this).val() === "") {
        $(this).remove();
    }
});

2018年2月9日 星期五

解決php上傳png圖檔如果縮圖就會變黑的問題

png圖檔上傳後縮圖就會變黑圖的問題!
上傳圖檔的程式需加上下列語法存入png的透明部分





2018年1月29日 星期一

使用css讓input欄位內的placeholder值在碰觸或是focus到時就清空

現在做表單時通常都會在input或textare欄位上加上placeholder,提示使用者目前要輸入的欄位項目,但是placeholder有個缺點是,通常點了該欄位後,要開始輸入文字才會消失,而不是focus到該欄位時就消失,這在使用上其實有點干擾。

在jquery上可以在點擊到該欄位時以
$("input").removeAttr('placeholder');
來處理,不過也有人不建議用removeAttr來移除,

那麼可以試試用下列css的方法來處理:

input:focus::-webkit-input-placeholder { color:transparent; }
input:focus:-moz-placeholder { color:transparent; }

這個方式可以支援大部分瀏覽器甚至到ie9,ie8及更早的版本則未測試過

2018年1月12日 星期五

php mysql欄位輸入前的過濾檢查,防止sql_injection或xss()等攻擊

除了送出表單前的輸入檢核碼外,建議每個欄位可以做下方三道的過濾

1.strip_tags();
把所有輸入內容內的html語法跟js碼去掉
用法:
strip_tags($mystring);

2.htmlspecialchars();
htmlspecialchars是最基本的防線,在strip_tags過濾後加上htmlspecialchars過濾可以把strip_tags處理不掉的部分,如"或'轉換成文字碼(譬如:" 會變成&quot;)
也有人說strip_tags可以不做但是htmlspecialchars一定要
用法:
htmlspecialchars($mystring);
2.mb_substr();
輸入的字數先砍長度,譬如限制最多只有500或5000,防止mysql欄位的溢位攻擊
建議加上utf-8,以防內容有英數字會造成砍完長度後的尾字變亂碼
ex: mb_substr( $string,0,500,"utf-8");  //只截取500字

3.mysql_real_escape_string:
過濾敏感字元,防sql_injection,加這道前mysql要先建立資料庫連結,有登入的欄位最好加上
例如:
$con=mysqli_connect("localhost","db_userName","db_passWord","dbName");
mysqli_real_escape_string($con, $value);

如果有紀錄ip的話,可多加一道
4.用正規表示式去掉ip非數字跟 . 的部分,防sql_injection跟xss()攻擊,或用php內建的ip檢查函式檢查:
			//取得使用者ip
			if(!empty($_SERVER['HTTP_CLIENT_IP'])){			
			  $i_useripServer = $_SERVER['HTTP_CLIENT_IP'];			
			}else if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
			 $i_useripServer = $_SERVER['HTTP_X_FORWARDED_FOR'];			
			}else{			
			 $i_useripServer= $_SERVER['REMOTE_ADDR'];
			}
			
			$i_userip = filter_var($i_useripServer, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);


另每個post進來的值最好另命參數後再組合進sql語法內
例:
$myData=$_POST['data'];
$sql="INSERT INTO tableName (t_data) VALUES ('{$myData}')";
sql的陳述式最好參數化處理,以避免SQL injection的風險:
例如原本下面的方式:
$query="SELECT * FROM dbName WHERE t_userid = '$userId'";
$result=mysqli_query($link,$query);
$count=mysqli_num_rows($result);	

最好改為下面的參數化陳述
$query = "SELECT * FROM dbName WHERE t_userid = ?";
$stmt = $link->prepare($query);
$stmt->bind_param('s',$userId); 
$stmt->execute();
$result = $stmt->get_result();

$count=mysqli_num_rows($result);

if($count>0){
	$row=mysqli_fetch_array($result);
    
    $dataOne = $row['data_one'];
    $dataTwo = $row['data_two'];
}

$stmt->free_result();
$stmt->close();

$mysqli->close();