2008年6月20日星期五

利用AJAX技术提高搜索引擎排名

  描述 嵌入在你的web页面中的导航元素能够降低你的搜索引擎评价排名并且降低你的网站的响应性能。本文作者想同你一起探讨如何使用AJAX技术来解决这两个问题。

  许多设计良好的web站点都包含大量的与实际内容相联系的可导航信息。用于导航的HTML标记能影响你的搜索引擎评价,而且能够改进访问者的页面下载体验感。在本文中,你会看到如何使用AJAX来创建更为集中的更快速加载的web页面。

  让我们使用一个例子作为开始。请考虑你现在阅读的文章,它有下列一些内容:

  · 一个其上有一些预定义的到Informit的各个部分的链接的页眉。

  · 在页眉下有一行,把本文放到Informit的目录结构之中(实际上,这是唯一的与目录相关的可导航元素)。

  · 一个位于右首的侧栏,其中有一些连接到流行文章和推荐内容的链接。

  · 一个页脚,还有一些永远不会改变的链接。

  上面的"混合"很可能会影响搜索引擎索引你的数据的方式:

  · 因为搜索引擎不能区别内容与导航文本,所以它们会把它们在你的页面中找到的一切进行索引。既然目录中的关键字与不相关的可导航关键字混合在一起,那么内容之间的关联大大减少。一些搜索引擎宣称,它们能够在被搜索到的页面(例如,固定的页眉和页脚)中发现重复的文本并且删除它们。但是,不要依赖这种可能性;即使它们实现了这种技术,也很可能不会一直可靠。

  · web页面中的外向链接影响你的内容的页面评价。尽管这可能提高流行的文章的评价排名(因为许多页面都链接到它们),但是所有的页面都链接到的内容(例如,隐私策略)通常得到最高的页面评价-这可能不是你一直关心的问题。在我的一个web站点中,最高的评价页面是用于把消息发送到web管理员的表单-而不是你想让用户首先在Google上找到的内容。

  注意

  即使你不使用站点地图,你也可以通过Google的站点地图用户接口来了解一下你的页面的页面排名情况。

  添加到一个web页面的可导航元素还可能影响使用低速互联网存取的用户,而如果web页面不使用DIV元素(Informit使用之)而使用表格时更是如此。在这种情况中,在把它显示给用户之前,整个表格必须被加载到一些web浏览器中。

  传统地,web设计者一般都使用框架集或通过构建整套的导航架构(广泛使用JavaScript代码)来实现导航与内容的分离。这两条途径都存在其缺点;因此,许多大型网站避免使用框架集就不足为奇了。

  借助于在AJAX框架中使用的技术,你可以为这一问题提供一种方案:

  · 每一个web页面仅包含可导航元素和实际内容的占位符。

  · 在web页面通过嵌入式框架(IFRAME)或使用XmlHttpRequest对象加载后,再装载这些可导航元素。

  · 然后,可导航元素的内容被合并到web页面内容中,从而产生一个不嵌入任何帧的干净的页面。

  在使用这种方法重新设计你的web页面之前,你需要考虑下列问题:

  · 搜索引擎仅将看到初始的web页面。你必须确保,该页面中包含到相关页面或到一个网站地图的链接。Informit网站中文章页眉上方的导航线和在页面的文章信息部分中的链接正好可以较好地实现这一目的。

  · 在他们的浏览器中禁止调用JavaScript的访问者将具有与搜索引擎相同的页面视图。你必须确保他们有受限的视图不会给你的网站的功能造成较大影响。

  · 你可能想在你的页面上保留一些静态内容。例如,Informit标识和版权信息必须一直显示给所有的访问者。

  对于每一个可导航元素的连续区域,你应该创建一个具有唯一id的独立DIV元素;这样以来,以后你可以在你的JavaScript代码中标识它。为了防止过度晃动,在创作页面期间,目录上方或右边的DIV元素的尺寸应该调整到非常接近你的可导航元素的实际大小;这样,当你使用希望的HTML代码来代替它们时内容就不会移动位置。为此,一种最巧妙的方法是把一个空的适当大小的DIV元素插入到该占位符处。

2008年6月18日星期三

两种HTTP连接方式POST&GET的比较

在MIDP2.0中提供了对TCP/IP层进行联网开发的支持,但是这仍然需要设备厂商和运营商的支持,而HTTP连接是MIDP规范中规定必须支持的连接方式,因此在选择开发联网应用程序的时候,HTTP连接仍然是很有竞争力的方式。当然如果你选择的目标设备支持Socket的话可以选择Socket连接方式,本文主要介绍HTTP的两种连接方式POST和GET的异同。

    HTTP协议是一种面向连接且无状态的联网方式,客户端向服务器发送请求,服务器处理后把响应传回客户端就断开连接。在我们选择连接方式的时候主要有两种可以选择POST和GET。

    当我们以GET方式发送数据的时候,数据按照如下形式封装成请求发送给服务器,我们可以看出数据都被包含在了URL中。
GET /index.Html?userid=joe&passWord=guessme HTTP/1.1
Host: www.mysite.com
User-Agent: Mozilla/4.0

下面是我们在J2ME开发中通过GET方式发送数据的代码片断
HttpConnection conn = null;
String url = "http://www.mysite.com" +
             "/index.html?userid=joe&password=guessme";
String agent = "Mozilla/4.0";

try {
conn = (HttpConnection) Connector.open( url );
conn.setRequestProperty( "User-Agent", agent );

     int rc = conn.getResponseCode();
... // process it
}
catch( IOException e ){
// handle the error here
}

     当我们使用POST方式发送数据的时候,数据被封装在URL和Header后面,中间以空行来分隔。例如
POST /login.jsp HTTP/1.1
Host: www.mysite.com
User-Agent: Mozilla/4.0
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

userid=joe&password=guessme

下面是我们按照POST方式发送数据时候的代码片断
HttpConnection conn = null;
String url = "http://www.mysite.com/login.jsp";
String agent = "Mozilla/4.0";
String rawData = "userid=joe&password=guessme";
String type = "application/x-www-form-urlencoded";

String encodedData = encode( rawData ); // user-supplied

try {
conn = (HttpConnection) Connector.open( url );
conn.setRequestMethod( HttpConnection.POST );
conn.setRequestProperty( "User-Agent", agent );
conn.setRequestProperty( "Content-Type", type );
conn.setRequestProperty( "Content-Length",
     encodedData.length() );

OutputStream os = conn.openOutputStream();
os.write( encodedData.getBytes() );

     int rc = conn.getResponseCode();
... // process it
}
catch( IOException e ){
// handle the error here
}

    从上面的代码我们可以看出,如果使用POST方法,通常我们应该设置一些Headers,可以通过setRequestProperty()方法完成,其中 Content-Type和Content-Length是非常重要的,在MIDP中经常使用的Content-Type是 application/octet-stream和application/x-www-form-urlencoded,前者用于发送二进制数据,后者可以用于发送属性-数值对。我们最好在联网的时候设置这两个Header,因为这样服务器将很容易的知道将有什么类型的数据,多少数据发送过来。

    在使用POST方法发送数据的时候,通常要涉及到io的知识,我们需要打开流,发送数据,关闭流。例如
    void postViaHttpConnection(String url) throws IOException {
        HttpConnection c = null;
        InputStream is = null;
        OutputStream os = null;

        try {
            c = (HttpConnection)Connector.open(url);

            // Set the request method and headers
            c.setRequestMethod(HttpConnection.POST);
            c.setRequestProperty("If-Modified-Since",
                "29 Oct 1999 19:43:31 GMT");
            c.setRequestProperty("User-Agent",
                "Profile/MIDP-1.0 Configuration/CLDC-1.0");
            c.setRequestProperty("Content-Language", "en-US");

            // Getting the output stream may flush the headers
            os = c.openOutputStream();
            os.write("LIST games\n".getBytes());
            os.flush();                // Optional, openInputStream will flush

            // Opening the InputStream will open the connection
            // and read the HTTP headers. They are stored until
            // requested.
            is = c.openInputStream();

            // Get the ContentType
            String type = c.getType();
            processType(type);

            // Get the length and process the data
            int len = (int)c.getLength();
            if (len > 0) {
                byte[] data = new byte[len];
                int actual = is.read(data);
                process(data);
            } else {
                int ch;
                while ((ch = is.read()) != -1) {
                    process((byte)ch);
                }
            }
        } finally {
            if (is != null)
                is.close();
            if (os != null)
                os.close();
            if (c != null)
                c.close();
        }
    }

     通过如上的比较,我们可以看出POST方法发送数据的时候将更加灵活,你可以发送二进制数据,甚至可以实现对象的序列化。而使用GET方式发送数据的时候我们只能把数据在URL中发送出去,如果参数过多则很不方便,还要受到URL长度的限制,因此在J2ME联网中我们推荐HTTP协议的POST方式。