一個小型線上網站的產生歷程

自學了一段時間web開發後面試了份全站實習工做(就是先後端包括服務器搭建都一我的完成)。而後就開始了第一次真實搭建一個線上運營的網站的歷程...javascript

整個網站包括6個可顯示頁面,其中3個爲動態生成頁面。因爲是企業的一個業務使用網站(就是用戶經過登陸咱們網站使用公司提供的某項業務),不涉及支付,涉及的數據庫表規模和實際日訪問量都不會太大,此外涉及一個用調用實際業務代碼(C代碼)的問題。php

先後個人主要開發時間大概是2周,2周後我基本已經閒着在關注安全問題和作些小改善了...因此估計出來的網站仍是比較粗糙的,不過實戰的過程當中確實會遇到不少以前本身瞎鼓搗不會遇到的問題,因而也便趁解決之機學到了很多,在此作一個歷程總結,但願對新手有用,也誠望高手賜教!css

因爲算新手,掌握或者說用過的東西只包括html/css,js,php,python,mysql,apache,可是對各類框架徹底不熟悉,第三方插件裏也只用過jquery和phpmyadmin,因此整個搭建思路很簡單,前端html/css+js/jquery搞定,後端典型的lamp加上postfix做爲郵件發送服務器,此外因爲boss比較喜歡qq郵箱的自動提示(其實就是發提示到微信端= =)功能,因此接收郵件這個功能是經過騰訊域名郵箱功能搞定的(能夠登陸domain.mail.qq.com按着步驟作,騰訊的提示仍是足夠的,原理基本上就是修改dns裏的mx記錄(該記錄決定了指定域名的郵件服務器ip地址)使得其餘人發送以指定域名結尾的郵件時會發送到騰訊的服務器上)。html

交代完背景後下面咱們先來開始雲服務器的搭建歷程。前端

先解決物理服務器問題:使用的是阿里雲的雲服務器,並且咱們在測試階段申請的是1G1核6個月免費那種,帶寬是1M,ubuntu 12.04系統(好像你們都推薦centos,不太小網站爲了方便安裝各類東西並且ubuntu其實穩定性還行啦),而後用cat /proc/cpuinfo 命令能夠看到阿里雲使用了Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz 的處理器仍是很良心的(想一想我這六個月免費用而後它給我個至強E5-2630)後來跑壓力測試(見http://www.cnblogs.com/yjf512/archive/2011/05/24/2055723.html)的時候發現這樣的配置每秒能夠處理12個請求,可是我以爲主要瓶頸是帶寬的限制,在服務器上使用top命令能夠看到峯值時cpu的空閒率在80%以上,內存大概剩餘200M的free,而我在測試發起端看到Transfer rate:          128.09 [Kbytes/sec] received,1M的帶寬下載速度通常按1/5算峯值,也差很少了。

java

阿里雲免費的是須要寫申請的等審批經過不想免費直接買了就能夠現用(固然企業用途的後面阿里雲會有備案程序招呼你,boss被迫在阿里雲寄的背景布前留下了一張「挺sb」(boss原話)的照片),固然域名是boss先在萬網上買好的,修改dns記錄綁定服務器的公網ip也是在上面搞定。(爲新手補充下知識:dns中的a記錄爲正向域名解析,決定類別人訪問你綁定的這個域名時域名會先映射成哪一個服務器的ip,而後實際最後都是根據ip找到服務器位置來獲取網頁內容,綁定的域名能夠指定先後綴,因此徹底能夠同一個域名,但前綴不同訪問的服務器也不同(eg.a.xxx.com,和b.xxx.com分別指向121.5.5.5和121.5.5.6兩個不一樣的ip)),在萬網上修改一個dns記錄後全球同步時間大概10分鐘,仍是挺給力的(同步後別人才能夠經過這個域名訪問你的服務器,不然只能經過直接的ip訪問)。python

服務器和域名綁定問題解決後開始服務器上的應用環境搭建工做了。ubuntu自帶python,因此主要是apache,postfix,php,mysql還有phpmyadmin(一個基於php的web端mysql數據庫管理工具)的安裝和配置,因爲我比較懶,因此選服務器的時候是直接在阿里雲上選了個鏡像(就是一個別人已經安裝配置好的操做系統)配上去(http://market.aliyun.com/imageproduct/16-122106003-jxsc000020.html?spm=5176.6883001.0.0.4yKKwv上面已經集成了php apache mysql還有phpmyadmin),不過若是用這個鏡像的話記得要在前面那個頁面中下載它的使用指南,否則就和我同樣一開始得本身去搞明白它的目錄結構了...不過最後我仍是由於要解決一個安全問題(php-cgi的query string注入可執行代碼漏洞)得本身從新去編譯安裝新版的php5.6(鏡像本身配的是5.2版的,這個漏洞要解決得本身給php5.2的源碼打補丁後從新編譯安裝——既然如此,不如直接編譯安裝php5.6好了,5.3和5.4的某個版本後已經把那個漏洞補上了~)mysql

此外,使用鏡像的好處是它在安全上也提供了很好的預先配置,好比linux的權限設置(owner-group-other),鏡像都作了到位的設置,若是不使用鏡像的話不少文件夾的權限都得本身去修改以提升安全性。而後,apache的httpd.conf文件,php的php.ini文件,mysql的my.cnf這三個配置文件也基於安全和併發量控制作了不少預先的設定,這些東西本身學的話須要查閱很多文檔,因此省事的辦法仍是使用鏡像,而後再經過一些安全檢測工具(有不少這樣的站長工具,好比360家的)看看鏡像上還存在什麼漏洞,把漏洞補了,再在代碼級上防止sql注入攻擊和作好必要的過濾驗證(使用session保持會話驗證狀態,正則表達式過濾非法數據等),架構上對sql的用戶權限作一些限制(好比用專門的帳戶做爲腳本運行時使用的帳戶,而後只給予所需的最低權限,如只給增查改),感受差很少對於一個不涉及支付的網站這樣的安全程度就足夠了(唔,還請高手們指正)。jquery

至於打算從頭開始的,能夠參考http://www.cnblogs.com/lynch_world/archive/2012/01/06/2314717.html 安裝php mysql apache phpmyadmin,或者你對安裝路徑有特殊要求的能夠各個官網下載源碼包查閱相關編譯參數後編譯安裝。而後安全上的配置就得本身從頭搗鼓了。linux

至於郵件服務器postfix,參考http://blog.csdn.net/bird_wang/article/details/4225113進行安裝和配置

而後經過php的mail函數便可發送郵件。至因而發送純文本仍是要發送html編碼的郵件以及如何加入郵件頭部請搜索mail函數的用法便可。
在我這個網站裏郵件的主要做用是用於用戶找回密碼時發送驗證連接。此外發現一個比較奇怪的現象,php裏發送郵件時插入換行符是使用\n,可是爲了使他生效筆者發現須要字符串使用雙引號擴起來
eg."用戶您好:\n"換行有效而‘用戶您好:\n’換行無效...

實際的開發中每每須要ssh登錄的服務器上進行操做,使用scp傳遞文件,這兩個命令的介紹資料挺多的能夠百度獲得。此外,傳遞文件的另外一種方式是創建ftp服務器的服務器端並在本身的電腦上安裝filezilla等ftp客戶端軟件,這樣能夠實現圖形界面的文件上傳(還支持批量)。服務器端可使用Pure ftp(參見http://www.cnblogs.com/ventry/archive/2012/06/04/2534444.html)

而後是實際的先後端代碼的編寫

因爲是公司的網站,不能夠開源,因此後面的內容主要以總結性的經驗形式出現...

先解決開發工具的問題

前端的高富帥開發工具——webstorm強烈推薦,可以編輯html,css,js代碼,同時支持各類高亮和提示(特別是支持jquery提示),用它開發前端一個字「爽」。下載安裝自行到官網(http://www.jetbrains.com/webstorm/),而後能夠試用30天(因而夠我此次的開發了),實在想長期用的話網上有共享出來的註冊碼,固然仍是但願你們支持正版。

後端的話我用的是vim,由於php和python都是腳本語言,不用編譯,而後vim用於代碼定位以及增刪查改等效率上的優點仍是比較明顯的。以及小型web開發,也不像編什麼算法題同樣須要常常看某個變量的值,實在須要的適合加個輸出語句編輯完一跑就知道了。(其實本質緣由仍是eclipse用得不熟悉?)

至於一些報錯提示信息,apache、php、mysql這三者的日誌文件都給予了足夠的提示。

而後服務器上有什麼確定本地就得跟着有什麼,大部分的開發調試工做通常都是在本地作的(因此前面那個安裝php mysql..的帖子仍是派上了用場),而到服務器上時可能就會發如今本地好好的代碼上去就各類問題...

下面列舉幾個在本地和服務器端遇到的問題:

1.解決apache上訪問 cgi腳本時老是在網頁中顯示出腳本的源代碼而不是執行結果的問題

2.python 在使用MySQLdb模塊時報Can't extract file(s) to egg cacheThe following error occurred while trying to extract file(s) to the Python eggcache的錯誤。

(python要和mysql交互能夠經過MySQLdb這個模塊(能夠參考http://www.cnblogs.com/rollenholt/archive/2012/05/07/2487137.html,比較新的版本的MySQLdb安裝前還須要機器上有安裝setuptools,百度解決便可))

3.啓動mysql時顯示:/tmp/mysql.sock 不存在的解決方法

其餘的問題也許由於我沒遇到或者由於比較常見就不一一列舉了,有其餘問題的朋友能夠留言與我討論。

接下來探討某些後端功能的實現方式:

1.會話狀態的保持

對會話狀態的保持有兩個做用,一個用於防止用戶訪問須要登陸以後才能訪問的頁面,一個是已登陸用戶訪問首頁時自動跳轉到已登陸頁面。

實現這個功能的主要方式是session,session的原理是在服務器端保存session數據,而在客戶端保存session數據的id(通常是保存在cookie裏),客戶端向服務器發起訪問時服務器經過id來取出對應的session數據(但注意php的默認session保存時間是24分鐘,若是在第一次請求後24分鐘內客戶端沒有發起第二次請求,則session會被服務器清空)。

php中session的使用

所以能夠在登陸腳本中爲已登陸用戶設置$_SESSION['logined']=true;而後對每一個須要檢驗登陸狀態的網頁(.php文件)在開頭加入一段php代碼用於檢驗$_SESSION['logined']是否已經設置(經過isset函數來檢查,不檢查直接訪問一個空的數組位置會報錯)以及是否爲true

<?php
if(!(isset($_SESSION['logined'])&&$_SESSION['logined']==true))
{
      header("location: index.php");   
    exit('1'); }
?>

這樣若是未登陸的用戶打算經過url直接訪問該頁面時就會自動發生跳轉,注意,header("location: index.php"); 語句必須在全部輸出語句以前才能實現跳轉功能(跳轉目的爲location: 後面指示的文件),此外,最好養成每一個跳轉語句後接上exit();語句(參數能夠本身選,只做爲退出時的返回值)以退出該腳本的執行,不然,儘管用戶經過瀏覽器沒法看到該頁面內容(由於跳轉到了另外一個頁面),可是若是採用網絡抓包工具,上述php代碼後面的內容(或者說執行結果)仍然能夠被捕獲(由於仍然發送到了客戶端),而這每每不符合程序的設計意圖。

2.線程安全地獲取插入mysql的條目的id

3.對用戶密碼的保存處理

通常咱們不該當保存明文的用戶密碼,除了涉及用戶密碼隱私外,在網站被入侵的狀況下,明文的密碼無疑正中黑客的下懷。

一種作法是保存屢次md5加密的結果,因爲md5不可逆,惟一的破解方式也是經過一個字典來暴力破解,所以通過屢次md5加密後的結果具備較可信的安全度。php中md5的使用方式很簡單,md5(md5($variable))返回的就是$variable兩次加密後的結果,此外,md5獲得的結果是32位字符(也多是16位),這也爲存放密碼的空間提供了上限。

4.正則匹配過濾非法輸入

在網絡上,咱們不能假設用戶傳回來的數據必定知足咱們原本設定好的格式和內容要求,好比在正常使用網頁時,也許咱們在某次數據通訊中在網頁代碼裏經過js的ajax發送回來一個整數類型的數據,而後在腳本中咱們根據這個整數進行處理。但實際上,用戶能夠操縱往服務器發送的數據,包括get,post等各類方式所傳遞的數據,對於黑客,這些數據中每每還包含能夠入侵的代碼,若是不對取得的數據加以驗證就直接進行使用,無異於把本身徹底暴露在這些入侵代碼之下。

所以一種過濾方式就是採用正則匹配來過濾,正則表達式的相關資料比較多能夠自行查找,而php中使用正則表達式有兩類庫,一類是preg開頭的一類是ereg開頭的,其中ereg開頭的遵照POSIX正則表達式規範(能夠參見http://blog.csdn.net/echo_qiang/article/details/5907679正則表達式在不一樣的規範中有所不一樣,特別是一些轉義字符)。在使用中,preg庫經常使用於從一段字符串中提取匹配的子串,而ereg可用於檢驗整個字符串是否匹配特定的正則表達式。

我在開發中使用的是ereg庫,由於ereg函數十分簡單地知足了個人需求

bool ereg(pattern,target) //pattern爲正則表達式字符串,target爲想要檢查是否匹配的字符串,若匹配函數返回true,不然爲false

好比我想檢查post傳輸的數據id是否是數字串,ereg("^[0-9]+",$_POST['id'])便可。

5.防止sql注入攻擊

sql注入攻擊通常發生於執行sql語句的時候,好比,mysql_query('select * from table1 where id = '.$_POST['id']); 因爲mysql是以特定字符爲一個sql語句的分隔符的,若是黑客在id數據裏插入這麼一個符號後在後面就能夠隨便加入他想執行的sql語句了,這種執行輕則毀壞數據表,重則破壞系統或盜取系統用戶信息,因此對於有數據庫交互的網站放置sql注入攻擊是必要的。(因此咱們會發現前面的正則匹配過濾的重要性,但同時咱們也會發現,有時還沒法預估用戶的輸入應該是什麼(好比若是你在網頁中放置了一個留言板等),那麼這種狀況下沒法使用正則匹配來過濾)

一種方式是對那些特殊的分隔符進行轉義,使用php的mysql_real_escape_string函數能夠達到對傳入的字符串進行轉義的效果,通常而言,這樣的轉義已經足夠。

但更正規的作法是採用一種稱爲動態參數綁定的方法。

咱們會發現,發生sql注入的緣由是由於咱們在動態生成一條sql語句時使用了字符串的拼接,而因爲特定分隔符的存在,這樣的拼接老是漏洞重重,而實際上,咱們須要的動態生成sql語句的動態程度只是但願某些參數能夠動態給定,因此實際上只要能規定只修改這個參數的內容而不影響sql語句的其餘部分便可達到防止sql注入攻擊的目的(就算黑客打了一長串sql注入代碼進來咱們也只是把它看成普通數據存起來而不是去執行它)。

php的mysqli_stmt類就知足了動態參數綁定的要求,能夠參考http://book.51cto.com/art/200909/154027.htm  和   http://blog.sina.com.cn/s/blog_0ee72b370101bmlo.html

惟一的缺陷是目前這個類在獲取執行結果時不支持參數數組(不像mysql_fetch_array($result,MYSQL_ASSOC);傳入MYSQL_ASSOC參數後便可獲得一個參數數組),只能按照順序逐個綁定結果存放變量。若是有高手知道其餘的支持動態參數綁定又支持返回參數數組結果的方法麻煩賜教!

後端的問題好像說得七七八八了,若是有什麼其餘但願探討的也歡迎留言!

下面進入前端,一個我以爲變化萬千的新世界:

前端的實如今我看來是一個充滿靈活性的世界,一種效果可能有不少種實現方式,而這些實現方式可能涉及運行性能,後期可維護性及擴展性(如MVC模型編程,面向對象思想等),web語義等諸多方面的考量,固然,對於像我同樣的剛入門者可能仍是以能實現一個功能爲目的。

1.html/css實現陰影蒙版覆蓋原網頁並顯示浮框的功能

2.jquery監聽input元素輸入

3.position:relative的用法

實踐過程當中發現position:relative的使用能夠完成不少效果設置和對某些細微定位的改善。

好比有時咱們會遇到<span>xxx</span><textarea ></textarea>,原本咱們但願xxx和textarea元素的最高那一行對齊,結果發現直接這樣寫不作設置的話xxx是和textarea元素的最後一行對其,若是textarea高度必定,那麼就能夠簡單經過position:relative來實現預想的效果(修改top屬性讓<span>元素往上偏移必定像素)

此外,常見的文字浮於圖片之上的方式也每每能夠經過position:relative實現。只要修改文字或圖片其中一者的position:relative對應的top或left屬性,而後調整二者的z-index便可。

position:relative相比於position:absulte的好處是它的位置能夠隨着元素原來所處位置的變化而自動變化(原本relative就是相對元素原來所處位置而言),而position:absulte這種硬編碼的方式容易致使後面不斷修改的須要。

4.div+css佈局記扎

這個部分因爲我的以爲實在是比較普遍的,因此另開一貼間歇性更新...不足之處還望見諒

前端的世界裏還有不少的見聞,但有些以爲可能比較瑣碎,大部分會爭取集中到前面提到的div+css佈局記扎裏更新,其它的可能以爲不是特別重要的發現略去不表,若是有感興趣探討的也歡迎留言。

最後談一下版本管理

原本像我這種一我的開發版本管理看上去不是很是必要,可是由於boss的要求仍是專門去學了下svn,可是後來有一次出了一個莫名其妙的bug時才發現版本管理的難得,直接svn diff命令找出修改的歷史,bug瞬間定位。

svn版本管理工具的使用

 而後實踐過程當中發現阿里雲的3690(svnserve的端口)端口本地127.0.0.1能夠訪問可是遠程就不行了...後來ping過也是ping不通,不知道是阿里雲把它禁了仍是怎麼的,但願有知道怎麼實現遠程svn的大蝦告知一二!

發現前面寫的日誌web實踐小項目<一>:簡單日程管理系統(涉及html/css,javascript,python,sql,日期處理)果真如今再看充滿着幼稚(原本以前還打算貼小項目的代碼忙完一段時間後如今看來仍是不要獻醜好了...)

寫得應該仍是有很多疏漏,歡迎指正討論!

相關文章
相關標籤/搜索