http://www.tkk7.com/zqli/archive/2006/08/29/66394.aspx
生成有4個隨機數字和雜亂背景的圖片,數字和背景顏色會改變,服務器端刷新(用history.go(-1)也會變)
原型參考ALIBABA??http://china.alibaba.com/member/showimage

------------產生驗證碼圖片的文件-----image.jsp-------------------------------------------

<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
Color getRandColor(int fc,int bc){//給定范圍獲得隨機顏色
????????Random random = new Random();
????????if(fc>255) fc=255;
????????if(bc>255) bc=255;
????????int r=fc+random.nextInt(bc-fc);
????????int g=fc+random.nextInt(bc-fc);
????????int b=fc+random.nextInt(bc-fc);
????????return new Color(r,g,b);
????????}
%>
<%
//設置頁面不緩存
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);

// 在內存中創建圖象
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 獲取圖形上下文
Graphics g = image.getGraphics();

//生成隨機類
Random random = new Random();

// 設定背景色
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);

//設定字體
g.setFont(new Font("Times New Roman",Font.PLAIN,18));

//畫邊框
//g.setColor(new Color());
//g.drawRect(0,0,width-1,height-1);


// 隨機產生155條干擾線,使圖象中的認證碼不易被其它程序探測到
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
????????int x = random.nextInt(width);
????????int y = random.nextInt(height);
????????int xl = random.nextInt(12);
????????int yl = random.nextInt(12);
????????g.drawLine(x,y,x+xl,y+yl);
}

// 取隨機產生的認證碼(4位數字)
String sRand="";
for (int i=0;i<4;i++){
????String rand=String.valueOf(random.nextInt(10));
????sRand+=rand;
????// 將認證碼顯示到圖象中
????g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));//調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成
????g.drawString(rand,13*i+6,16);
}

// 將認證碼存入SESSION
session.setAttribute("rand",sRand);


// 圖象生效
g.dispose();

// 輸出圖象到頁面
ImageIO.write(image, "JPEG", response.getOutputStream());


%>

---------------使用驗證碼圖片的文件---------a.jsp------------------------------------

<%@ page contentType="text/html;charset=gb2312" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>認證碼輸入頁面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<form method=post action="check.jsp">
<table>
<tr>
<td align=left>系統產生的認證碼:</td>
<td><img border=0 src="image.jsp"></td>
</tr>
<tr>
<td align=left>輸入上面的認證碼:</td>
<td><input type=text name=rand maxlength=4 value=""></td>
</tr>
<tr>
<td colspan=2 align=center><input type=submit value="提交檢測"></td>
</tr>
</form>
</body>
</html>

-----------------驗證的頁面----------check.jsp

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<title>認證碼驗證頁面</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>

<body>
<%
String rand = (String)session.getAttribute("rand");
String input = request.getParameter("rand");
%>
系統產生的認證碼為: <%= rand %><br>
您輸入的認證碼為: <%= input %><br>
<br>
<%
??if (rand.equals(input)) {
%>
<font color=green>輸入相同,認證成功!</font>
<%
??} else {
%>
<font color=red>輸入不同,認證失敗!</font>
<%
??}
%>
</body>
</html>
代碼:
DOWNLOAD /upload/article/a200461101741.rar[/DOWNLOAD]

本頁頁面地址:

投票評分(記入本貼作者的專家分)

???? 非常好還行一般扔雞蛋 ???????? 投票總得分: / 投票總人次:

用戶評論列表

#1679 評論作者: gree001 發表時間: 2004-08-20 04:58 下午 E-mail: gree001@tom.com

圖片沒有生成是個紅叉。。
這是。。。

#1680 評論作者: gree001 發表時間: 2004-08-20 06:21 下午 E-mail: gree001@tom.com

本機測試通過[windows2000 professional+tomcat4.1.24+jdk1.4.1_02],
??但在199上測試沒有通過[redhat linux 7.3+tomcat4.1.24+jdk1.4.2_03],
??應是生成Graphics 對象出錯[Graphics g = image.getGraphics();]
請指點。

#1683 評論作者: designlee 發表時間: 2004-08-21 11:00 上午 E-mail: designlee@sohu.com

不錯,在linux下出問題

#1689 評論作者: gree001 發表時間: 2004-08-23 08:45 上午 E-mail: gree001@tom.com

怎么解決呢?

#1694 評論作者: gree001 發表時間: 2004-08-23 04:35 下午

解決了。linux下用startx啟動xwindows測試環境可實現

#1914 評論作者: 發表時間: 2004-09-23 12:20 下午

不行啊,是把叉

#1934 評論作者: xiaohanne 發表時間: 2004-09-27 02:43 下午

windows下面應該沒問題,可能是爛awt在linux下不能用吧,不行的那位請把你的環境寫出來,讓我看看

#2059 評論作者: santafeng 發表時間: 2004-10-26 04:40 下午 E-mail: santafeng@sina.com

用jbx+resin調試出來是叉,有沒有好辦法解決?謝謝.

#3188 評論作者: virons 發表時間: 2005-05-14 11:03 上午 E-mail: wwllr@163.com

linux下用startx啟動xwindows測試環境可實現,但是如果linux作服務器時會存在一定的安全隱患的,如果服務器重啟,還要手動startx一下。不知道有沒有更好的辦法?

#3201 評論作者: gongjiezi 發表時間: 2005-05-16 04:53 下午 E-mail: gongjiezi@163.com

windows下測試成功.
非常感謝.
紅叉的原因應該是把路徑弄錯了.
把生成圖片的那個jsp寫成servlet更好一點.

#3206 評論作者: cedar 發表時間: 2005-05-16 07:28 下午 E-mail: cedar1979@163.com

請問如果在linux環境下,要往動態圖片上寫中文,需要怎么設置呢。嘗試了很久,還是弄不出來

#3256 評論作者: 后知后覺 發表時間: 2005-05-21 01:25 下午 E-mail: heyman@eyou.com

WINDOWS環境下,很好通過..
謝謝作者...期待ING,你新作品

#3286 評論作者: gree001 發表時間: 2005-05-26 08:45 上午

virons 可以寫一個腳本,服務器啟動之后,自動啟動startx

#3287 評論作者: gree001 發表時間: 2005-05-26 08:46 上午

可以寫個腳本,linux重啟動的時候,自動執行startx

#4033 評論作者: ssmax 發表時間: 2005-08-11 10:43 上午

紅叉是因為linux下面的jsp可能會有幾個空行輸出,所以干擾了圖片的正確字節,圖片格式就有問題了,只要把jsp改為servlet就可以解決問題,如果拋出exception就用
-Djava.awt.headless=true
加到服務器jvm啟動腳本里面去

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;
import java.util.*;

import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
//import com.sun.image.codec.jpeg.*;

public class vImage extends HttpServlet
{
????????public void init(ServletConfig conf) throws ServletException
????????{
????????????????super.init(conf);
????????}
????????
????????public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
????????{
????????????????res.setContentType("image/jpeg");
????????????????res.setHeader("Pragma","No-cache");
????????????????res.setHeader("Cache-Control","no-cache");
????????????????res.setDateHeader("Expires", 0);
????????????????HttpSession session = req.getSession();
????????????????
????????????????// 在內存中創建圖象
????????????????int width=60, height=20;
????????????????BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
????????????????
????????????????// 獲取圖形上下文
????????????????Graphics g = image.getGraphics();
????????????????
????????????????// 生成隨機類
????????????????Random random = new Random();
????????????????
????????????????// 設定背景色
????????????????g.setColor(getRandColor(200,250));
????????????????g.fillRect(0, 0, width, height);
????????????????
????????????????// 設定字體
????????????????g.setFont(new Font("Times New Roman",Font.PLAIN,18));
????????????????
????????????????// 畫邊框
????????????????//g.setColor(new Color());
????????????????//g.drawRect(0,0,width-1,height-1);
????????????????
????????????????// 隨機產生155條干擾線,使圖象中的認證碼不易被其它程序探測到
????????????????g.setColor(getRandColor(160,200));
????????????????for (int i=0;i<155;i++)
????????????????{
????????????????????????int x = random.nextInt(width);
????????????????????????int y = random.nextInt(height);
????????????????????????int xl = random.nextInt(12);
????????????????????????int yl = random.nextInt(12);
????????????????????????g.drawLine(x,y,x+xl,y+yl);
????????????????}
????????????????
????????????????// 取隨機產生的認證碼(4位數字)
????????????????String sRand="";
????????????????for (int i=0;i<4;i++)
????????????????{
????????????????????String rand=String.valueOf(random.nextInt(10));
????????????????????sRand+=rand;
????????????????????// 將認證碼顯示到圖象中
????????????????????g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
????????????????????????// 調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成
????????????????????g.drawString(rand,13*i+6,16);
????????????????}
????????????????
????????????????// 將認證碼存入SESSION
????????????????session.setAttribute("post_validate_code",sRand);
????????????????
????????????????// 圖象生效
????????????????g.dispose();
????????????????
????????????????// 輸出圖象到頁面
????????????????ImageIO.write(image, "JPEG", res.getOutputStream());
????????????????//JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(res.getOutputStream());
????????????????//encoder.encode(image);
????????}
????????
????????public void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
????????{
????????????????doGet(req,res);
????????}
????????
????????//給定范圍獲得隨機顏色
????????private Color getRandColor(int fc,int bc)
????????{
????????????????Random random = new Random();
????????????????if(fc>255) fc=255;
????????????????if(bc>255) bc=255;
????????????????int r=fc+random.nextInt(bc-fc);
????????????????int g=fc+random.nextInt(bc-fc);
????????????????int b=fc+random.nextInt(bc-fc);
????????????????return new Color(r,g,b);
????}
}

#4034 評論作者: ssmax 發表時間: 2005-08-11 10:49 上午

紅叉是因為linux下面的jsp可能會有幾個空行輸出(萬惡的resin。。。。),所以干擾了圖片的正確字節,圖片格式就有問題了,只要把jsp改為servlet就可以解決問題,如果拋出exception就用
-Djava.awt.headless=true
加到服務器jvm啟動腳本里面去

#4035 評論作者: ssmax 發表時間: 2005-08-11 10:58 上午

看看resin jsp生成的源程序吧(萬惡的空行啊),一開頭就插3個空行。。。。

pageContext.write(_jsp_string0, 0, _jsp_string0.length);
??????pageContext.write(_jsp_string0, 0, _jsp_string0.length);
??????pageContext.write(_jsp_string0, 0, _jsp_string0.length);

private static byte []_jsp_string0;
??static {
????_jsp_string0 = "\r\n".getBytes();
??}

#4236 評論作者: SunnyXiao 發表時間: 2005-08-25 02:26 下午

jcaptcha使用起來更方便

#4648 評論作者: ssmax 發表時間: 2005-09-22 12:41 下午

有空看了一下resin的源代碼,終于知道resin產生空行的原因:
把jsp解釋生成java文件的時候碰到jsp語句就會抽起來解釋,可是jsp語句后面的\r\n換行標記(一般大家都有換行吧)就會作為字符輸出,所以就造成了輸出的換行,比如大家寫jsp總有一句<%@ page contentType="text/html;charset=UTF-8" language="java" %>之類的在第一行,之后換行,轉成java文件就會輸出一個空行了。

上面那個行為是所有服務器都存在的,無論resin或者tomcat都有,區別就在tomcat生成的靜態頁面是直接out.print的,每次訪問內存都要生成一次臨時字符,但是resin就會把這些字符作為servlet的變量,這樣一個servlet初始化的時候就會生成,并且用遠存在,請求的時候輸出變量就可以了。

如果你有一個很多字符和程序的頁面,使用resin就可以看到有_jsp_string0、_jsp_string1。。。。很多,總之程序段之間的頁面字符會一直按序號生成下去。

#6000 評論作者: jackee 發表時間: 2005-11-15 09:59 上午

我的是resion,windows環境,也出現紅叉?

#7205 評論作者: bluesky 發表時間: 2005-12-25 10:51 上午

http://blog.csdn.net/ronger924/archive/2004/12/23/226030.aspx

Linux用Java處理圖片問題。(http://www.tmingtxing.com)

#8990 評論作者: hotsunn 發表時間: 2006-03-10 03:14 下午

為什么我的老是出現:
org.apache.jasper.JasperException: getOutputStream() has already been called for this response
???? 我應該怎么改呢?請指教!!!
??

#17000 評論作者: soke128 發表時間: 2006-06-08 07:40 下午 E-mail: soke128@sohu.com

謝謝..在Windows下測試成功,沒有任何異常

acegi內置了對CAS的支持。這里的CAS是3.0。建立CAS server是一個比較簡單的事情。CAS server就是一個標準的war文件,把它發布就可以運行。需要做的僅僅是調整登陸和其他一些頁面。先了解一下CAS如何實現SSO。
例子:原有系統A和系統B,現在在它們之間做SSO。
很顯然,系統A和B都是CAS client。首先是訪問系統A,干掉A的登陸頁面,在A的入口判斷有沒有Ticket(票據),如果沒有則重定向到CAS server,在CAS server提供Credential(大多數情況就是用戶名和密碼)。CAS server的作用非常簡單:就是來驗證用戶密碼。正確,則發送Ticket。CAS有5種Ticket,分別是TGC(通過cookie發送的ticket),ST(Service Ticket),PGT,PGTIOU,PT。其中PGT,PGTIOU,PT屬于代理ticket,這里不作討論。具體可以參考
http://www.tkk7.com/openssl/archive/2006/04/26/SSO_CASProxy.html
TGC和ST的關系可以打個比方:
我去中央電視塔去玩,結果發現地下還有個海底世界。SSO前我是這么玩的:先去電視塔買張門票,玩完了;再去海底世界買張門票,玩完了。發現真累,兩個景點這么近還要買兩次門票,就不能搞個通票嗎?于是就SSO。于是這樣:我先去電視塔,門衛告訴我你不能進去要買票,于是把我送到通票售票處(CAS server)買票(登錄),買吧,于是給了我兩張票,注意,是兩張,一張發到我手里,上面寫著僅限電視塔使用(ST);靠,不是通票嗎,咋僅限電視塔使用?別急,還有一張票(TGC)通過cookie發送你看不見。人家說了保證沒問題,我咋辦,這是人家的規矩,那就先去玩吧。出了電視塔我直撲海底世界,
門衛說要海底世界票,不會吧,我買的通票啊,門衛說不著急,又把我送回通票售票處(CAS server),通票售票處(CAS server)一看,發現我有TGC,嘿嘿,這家伙買過票了不用再買(不用再登錄),于是換我一張票(ST)上面寫著僅限海底世界使用,于是我就拿著這張票又去海底世界了。于是我明白了啥是SSO了,不就是把買票改成換票了嗎?
比方完了,最開始的例子也就不往下繼續了。需要注意的是系統A和B整合SSO需要把A、B的用戶密碼集中管理,你說A中我的用戶名是張三,B中是李四,SSO能不能幫我自動識別,回答是不行的。
繼續Acegi的整合。
CAS server是做用戶密碼驗證,具體的權限授權的工作還是在各個單個系統里,也不應該交給它管。做用戶密碼驗證需要AuthenticationHandler。這個具體就是根據Credential返回一個boolean值來判斷你輸入的用戶密碼正不正確。acegi提供了一個實現。
以一個典型的web訪問來說明整個過程
1、用戶訪問一個受acegi安全保護的頁面或業務方法;
2、用戶沒有登陸的話顯然會拋出AuthenticationException
3、配置exceptionTranslationFilter捕獲這個異常重定向到CAS server登陸頁面

??????? < bean? id ="exceptionTranslationFilter" ?class ="org.acegisecurity.ui.ExceptionTranslationFilter" >
????????????
< property? name ="authenticationEntryPoint" >< ref? local ="casProcessingFilterEntryPoint" /></ property >
????????
</ bean >
????????
????????
< bean? id ="casProcessingFilterEntryPoint" ?class ="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint" >
????????????
< property? name ="loginUrl" >< value > https://my.company.com/cas/login </ value ></ property >
????????????
< property? name ="serviceProperties" >< ref? local ="serviceProperties" /></ property >
????????
</ bean >
????????
????????
< bean? id ="serviceProperties" ?class ="org.acegisecurity.ui.cas.ServiceProperties" >
????????????
< property? name ="service" >< value > https://server.company.com/myapp/j_acegi_cas_security_check </ value ></ property >
????????????
< property? name ="sendRenew" >< value > false </ value ></ property >
????????
</ bean >

serviceProperties里的service屬性即在CAS server登陸完畢后由CAS server重定向回來的頁面
??https://my.company.com/cas/login?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check
4、CAS server檢查是否有TGC ,沒有則登陸,登陸后返回。這里屁股后面跟著的即ST,TGC通過cookie一并發送到客戶端。
?? https://server.company.com/myapp/j_acegi_cas_security_check?ticket=ST-0-jhsdfguwgeds
5、配置casProcessingFilter來處理返回ST(和以前的authenticationProcessingFilter比較類似)

??? < bean? id ="casProcessingFilter" ?class ="org.acegisecurity.ui.cas.CasProcessingFilter" >
????????
< property? name ="authenticationManager" >< ref? local ="authenticationManager" /></ property >
????????
< property? name ="authenticationFailureUrl" >< value > /casfailed.jsp </ value ></ property >
????????
< property? name ="defaultTargetUrl" >< value > / </ value ></ property >
????????
< property? name ="filterProcessesUrl" >< value > /j_acegi_cas_security_check </ value ></ property >
????
</ bean >

6、配置authenticationManager

??? < bean? id ="authenticationManager" ?class ="org.acegisecurity.providers.ProviderManager" >
??????
< property? name ="providers" >
?????????
< list >
????????????
< ref? local ="casAuthenticationProvider" />
?????????
</ list >
??????
</ property >
???
</ bean >
???
??
< bean? id ="casAuthenticationProvider" ?class ="org.acegisecurity.providers.cas.CasAuthenticationProvider" >
????????
< property? name ="casAuthoritiesPopulator" >< ref? local ="casAuthoritiesPopulator" /></ property >
????????
< property? name ="casProxyDecider" >< ref? local ="casProxyDecider" /></ property >
????????
< property? name ="ticketValidator" >< ref? local ="casProxyTicketValidator" /></ property >
????????
< property? name ="statelessTicketCache" >< ref? local ="statelessTicketCache" /></ property >
????????
< property? name ="key" >< value > my_password_for_this_auth_provider_only </ value ></ property >
????
</ bean > ?

具體作用的是casAuthenticationProvider,casAuthenticationProvider通過 casProxyTicketValidator來校驗ST

???? < bean? id ="casProxyTicketValidator" ?class ="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator" >
????????
< property? name ="casValidate" >< value > https://my.company.com/cas/proxyValidate </ value ></ property >
????????
< property? name ="serviceProperties" >< ref? local ="serviceProperties" /></ property >
????
</ bean > ?

casProxyTicketValidator又具體實現調用了CAS Client library里的ProxyTicketValidator校驗ST,ProxyTicketValidator?就比較有意思了,它做了個HTTPS請求CAS server,結果還是CAS server來校驗ST(繞了一大圈)
?https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check
?重新回到CAS server,它接受到這個HTTPS請求,檢查ST是否與對這個service發行的ST吻合,吻合的話CAS server就會發回一個肯定的XML回復,里面包含了用戶名(username)。剩下的就EASY了,casProxyTicketValidator解析XML,casProxyDecider處理代理,casAuthoritiesPopulator根據解析后的XML獲得user,最后就是casAuthenticationProvider構造Authentication(這里是CasAuthenticationToken)
7、重新回到casProcessingFilter,它將Authentication放入HttpSession
這樣就完成了整個過程

http://www.tkk7.com/RongHao/archive/2006/08/29/66389.html



Uche Ogbuji (uche@ogbuji.net), 首席顧問, Fourthougth, Inc.

2006 年 7 月 31 日

擁有大量預算作為后盾的 Web 設計人員可以獲得任何所需的資源,從而可以把他們的想像力付諸于 Web 體驗。他們可以聘請專業攝像師來制作引人注目的照片;可以請最好的 HTML 和 CSS 專家來創建適用于多種瀏覽器的復雜布局;可以指導圖形藝術家根據企業服裝來創作華麗的裝飾物;可以聘請專業文案人員起草迷人的散文。最大的好處是,他們能雇傭大量測試用戶和關注小組來確保網站吸引人、便于使用并能按照預期進行工作。

但是,并不是所有的 Web 設計人員都這樣幸運!不幸的是,有些設計人員必須用很少的錢來創建網站,并且對 Web 體驗的預期并不見得很低。在這種情況下,您必須尋求一切可以獲得的幫助。多半來說,Web 開發人員和設計人員在與同事共享知識和成就方面是非常慷慨的。當您共享時,同事們通常會努力地糾正并增強您的作品,使其變得更加精致、bug 更少,并會提供您自己的關注小組和質量保證。這意味著您可以找到大量免費材料。如果您知道去哪里找的話,就可以填補低預算 Web 開發運營情況下的一些漏洞。在本文中,我將介紹各類免費的 Web 資源,以及對一些貌似免費,實其不然的 Web 資源的警告。

創造性的公用

首先介紹 Creative Commons(CC),它本身不是免費資源的來源,而是提供免費資源的人們所使用的許可證的來源。用他們自己的話說:CC 是一個非營利性組織,為創造性作品提供靈活的版權許可。您可以選擇一個 CC 許可,以允許所有者要求您在使用所有者的作品或修改他們的作品時給予他們榮譽(歸屬條款);可以限制自己作品僅用于非營利性組織;可以要求任何對您作品所作的更改必須在與原條款相同的條款下共享(類似共享的條款)。還有其他條款,您可以組合這些條款。例如,一個常見的 CC 許可是Attribution Share Alike 許可。

CC 已取得了巨大成功 —— 來自 CC 許可的作品主體十分龐大,并且每天都在擴大。文學、圖像、音樂等作品都可以在 CC 許可下提供。只要滿足限制,您可以自由地在網站上使用任何這些作品。要了解如何找到 Web 設計的任何免費產品,第一步是了解如何搜索在 CC 許可下提供的材料。您可以使用 CC 搜索引擎頁面直接獲得來源,這允許您利用搜索引擎(如 Google 和 Flickr)和免費資源收集(如 Flick 和 DMusic) 的專業搜索功能。

樣式元素

好的樣式表是好網站的骨架 —— 尤其是層疊樣式表 (CSS)。不幸的是,瀏覽器中多變的支持意味著很難開發好的樣式表。依靠免費樣式表,至少是樣式元素的免費模塊,您可以省去大量精力和測試工作。許多站點提供 CSS 說明和示例,但我的關注點是我找到的站點,大多數都有 CSS 材料,您可以用于快速地組裝成自己的站點。有一個由頂級 Web 專業人士開辦的以期刊形式出現的站點:A List Apart,著重于 Code 和 Design 主題。CSS Intensivstation Templates 專注于幾個用于結構化站點的主要的布局樣式。

最有名的 CSS 交換地是 CSS Zen Garden,但您在使用此網站時必須格外小心。CSS Zen Garden 旨在展示 CSS 的強大功能。CSS 是分離內容和形式的好方法。但起初許多 Web 開發人員回避 CSS,因為他們認為如果不用傳統的 HTML 技巧(如布局表格和隱藏圖像),就創建不出同樣令人難忘的效果。CSS Zen Garden 通過漂亮的樣式證明這一認識是錯誤的。其中有一個單獨且共享的內容片段,Web 設計人員創建了頁面來以某種獨特方式顯示這些內容。他們使用巧妙的布局、迷人的圖像和顏色,通常創作出某種主題,如大海或博物館風格的主題。CSS Zen Garden 不能作為模板的集合。您可以在大多數 CSS 貢獻中顯示的警告中看到以下說明:

此設計不是模板。未經設計者的書面許可,不得復制。但是,可以隨意研究 CSS 并在其他地方使用學到的技術。

此外,許多貢獻者使用非免費的圖像。站點維護人員請求貢獻者在非商業 Creative Commons 許可下提供他們的 CSS(參見 參考資料),所以復制 CSS 通常是安全的做法,但要確保檢查貢獻者 CSS 文件的開頭部分。

圖像

專業網站會使用各種圖像,從照片到藝術家的繪畫到圖標和符號,等等。一些站點提供免版稅的圖像。有一個項目值得您關注,即 Open Clip Art Library,它是一個貢獻的、可下載的剪貼畫的集合。圖像的范圍包括從小而簡單的圖像到大而復雜的圖像。大多數圖像是可縮放矢量圖形 (SVG) 格式,它是一種開放的、基于 XML 的格式。SVG 增強了對瀏覽器的支持,但它尚不通用,所以 Open Clip Art Library 包括每個圖像的 PNG 版本。您可以瀏覽或搜索網站上的圖像,但可能只想下載一個發行版,所以可以脫機瀏覽。圖形的質量類似于您在商店購買的許多剪貼畫集合中找到的圖像的質量。當我需要符號、圖標和其他資源(如高亮顯示)時,通常會瀏覽 Open Clip Art Library,但 MaxPower Free Icons 是一組很好的到免費圖標集合的鏈接。說到商店里的剪貼畫集合,即使已經購買,仍有許多限制。一些剪貼畫需要商業使用版稅。如果購買此類集合,請確保檢查 End User License Agreements。

當需要照片時,我經常會訪問前面提到過的 Flickr 的 CC 照片庫,但是我通常是通過 Yotophoto 到達那里的,Yotophoto 是從 CC 變體到 Public Domain 的一個免費許可照片的搜索聚合地。我最喜歡的一個資源站點是 stock.xchng。此站點包括大量極高品質的照片,并有一個非常好用的搜索引擎。不是所有的照片都是免版稅的,但大多數是!您甚至可以查看是否有照片的模型發行,這是決定使用包含人像的照片時要考慮的一個重要因素。一個規模較小、尚不精致,但仍十分有用的站點是 Open Photo,它只包含經 CC 許可的照片。我還使用 MorgueFile,這個站點類似于 stock.xchng 站點,具有搜索和豐富元數據方面的類似優點。MorgueFile 上的所有圖像受到專門許可(不基于 CC)的約束,但免除了個人或商業作品的版稅。我喜歡 MorgueFile FAQ 中針對他們為什么提供免費圖像的解答: 此網站遵循傳統的萬維網。它致力于倡導自由觀點和交換。

設計工具

一些 Web 設計人員和公司提供聯機工具來幫助其他用戶并提高他們自己的社區形象。最常用的是顏色方案工具,它允許您為自己的站點選擇富有美感的、令人愉快的一組顏色。在搭配顏色方面,我的確沒有世上最好的眼力,所以我感謝諸如 Wellstyled.com 的 Color Scheme Generator 這樣的網站。另一個提供更多有關如何組裝方案的站點是 SiteProCentral.com's HTML Color Code Combination Chooser

最流行的 Web 瀏覽器也是最奇怪的瀏覽器。多年來,Web 設計人員不得不應對 Microsoft Internet Explorer 5 和 6,包括 Macintosh 和 Windows 版本之間的差異。Microsoft 正在開發 7 版瀏覽器,他們承諾新版本具有更好的標準兼容性,但是另一方面 Dean Edwards 已經開發了 JavaScript 解決方案。引用該網站的話:

[Dean Edwards'] IE7 是一個 JavaScript 庫,使 IE 的行為像標準兼容的瀏覽器。它修復了許多 CSS 問題并使透明 PNG 在 IE5 和 IE6 下正常工作。

當您設計網站時,記住 Macintosh 用戶是十分重要的。如果購買測試用的 Mac 機不是一個選擇的話,您應感謝 Daniel Vine,因為他創建了 iCapture。您可以在此站點指定 URL、搜索看上去像 Mac 機上的 Safari Web 瀏覽器顯示的 PNG 圖像。Edwards 還提供 ieCapture,允許查看您的站點在 Macintosh IE7 beta 中的顯示效果。

完全 Web 布局和模板

有時即使獲得以上所有幫助,我還是不能創建引人注目的網頁。我可能想要一切,幸運的是可以在一些網站中找到免費的完整頁面布局,包含 HTML(經常是 XHTML)模板、圖形、樣式表、高亮顯示等。Open Web Design 有近 2000 個各種品質的完整模板。該網站有一個評級系統,有時會進行設計人員競賽來擴大其收集量。Open Source Web Design 是一個具有類似規模的網站。?

結束語

在本文中,您了解了許多資源,可以從中獲得免費資料和工具以改進您的網站。即使您有預算來得到頂級的專業幫助,如果熟悉 Web 設計的最新技術,還是會很有幫助的。所幸的是,最新技術幾乎不被隱藏或無法訪問,它們總是免費的。如果有機會,我還鼓勵您進行共享,比如為我提到的網站做貢獻。畢竟,Web 美學的浪潮會水漲船高