world_eyes

记录点滴的地方

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  10 随笔 :: 3 文章 :: 1 评论 :: 0 Trackbacks

2009年4月11日 #

  在Android的应用程序开发中,通常使用的是Java语言,除了要熟悉Java语言的基础外,还需要了解Android提供的Java扩展功能。

一、重要包描述

Android.app:提供高层的程序模型、提供基本的运行环境。

Android.content:包含对各种的设备上的数据进行访问和发布的类。

Android.database:通过内容提供者浏览和操作数据库。

Android.graphics:底层的图形库,包含画布、颜色过滤、点、矩形,可以将它们直接绘制到屏幕上。

Android.location:定位和服务的相关类。

Android.media:提供了一些管理音频视频的媒体接口的相关类。

Android.net提供了关于网络访问的类,超过通常的java.net.*接口。

Android.os:提供了系统服务,消息传输,IPC机制。

Android.opengl:提供了OpenGL的工具。

Android.provider:提供类访问Android的内容提供者。

Android.telephony:提供与拨打电话相关的API交互

Android.view:提供基本的用户界面接口框架。

Android.util:涉及工具性的方法,例如时间日期型的操作。

Android.webkit:默认浏览器操作接口。

Android.widget:包含各种U元素,在应用程序的屏幕中使用。

二、Android的相关文件类型概述

Java文件---应用程序源文件

Android的应用必须使用Java来开发。

Class文件---Java编译后的目标文件。

不想J2SE,java编译成class文件就直接可以运行,Android平台上的class 文件不能直接在Android平台上运行。由于google使用了自己的Dalvik来运行应用,所以这里的class也肯定不能在Android Dalvik上运行,Androidclass文件实际上只是编译过程的中间目标文件,需要链接成Dex文件才能运行在Dalvik上。

Dex文件---Android平台上的可执行文件。

Dalvik执行的并非是Java字节码,而是另一种字节码:dex格式的字节码(Java字节码->dex字节码)。Dalvik可以执行许多VM而不会占用太多的Resource.

APK 文件---Android上的安装文件

APKAndroid安装包的扩展名,一个Android安装包包含了与某个应用程序相关的所有文件,APK文件将AndroidMainfest.xml文件、应用程序代码(DEX)文件、资源文件和其他文件打成一个压缩包。一个工程只能打进一个.apk文件。

 

三、Android ADB工具的使用

ADBAndroid提供的一个通用调试工具,借助这个工具,我们管理手机模拟器的状态。

1.ADB功能操作

快速更新设备或手机模拟器的代码,如应用或Android系统升级。

在设备上运行shell命令

管理设备或手机模拟器上的预定接口

在设备或手机模拟器上复制、粘贴文件

2.ADB的常用操作

安装应用到模拟器

adb install app.apk

Android没有提供一个卸载应用的命令,只能手动删除:

Adb shell

Cd data/app

Rm.app.apk

进入设备或模拟器的shell

Adb shell

通过以上命令,可以进入设备或模拟器的shell环境中,在这个shell中,你可以执行各种Linux的命令,另外如果只想执行一条shell命令,可以采用以下方式:

Adb shell[command]

如:

Adb shell emesg

会打印出内核的调试信息

发布端口

可以设置任意的端口号,作为主机箱模拟器或设备的请求端口。如:

Adb forward tcp 5555 tcp8000

复制文件

复制一个文件或目录到设备或模拟器上;

Adb push

如:

Adb push test.txt/tmp/test.txt

Adb pull

如:

Adb pull /Android/lib/libwebcore.os

搜索/等待模拟器、设备实例

取得当前运行的模拟器、设备的实例列表及每个实例的状态或等待正在运行的设备

Adb devices 

Adb wait-for-device

查看debug报告

Adb bugreport

记录无线通信日志

无线通信日志非常多,在运行时没必要记录,可以通过命令设置记录

Adb shell

Logcat -b radio

获取设备ID和序列号

Adb get-product 

Adb get-serialno

访问数据库SQLite3

Adb shell

Sqlite3

posted @ 2011-03-09 10:25 world_eyes 阅读(336) | 评论 (0)编辑 收藏

转载来的,遇到这样问题的朋友应该不多,我是配置好环境了,也装了个PHP的CMS测试过了,PHPMYADMIN运行也正常,但是运行另外一套 PHP网站程序就出现HTTP 500服务器内部错误,还好找到了解决办法!

感谢Oliver分享,原文 地址:http://tech.flyingcat.cn/?p=212

在IIS + PHP的环境下安装phpmyadmin或wordpress的时候经常会发生一个奇怪的现象,例如:phpmyadmin安装的web文件夹根目录的话 打开显示HTTP 500服务器内部错误,但将网站放到一个子目录下就没问题。
这个问题的原因在于phpmyadmin和wordpress等程序的index.php文件中都用到了require(./xxx.php)这样的语 句。

解决办法1
把里面的require(./xxx.php)改成 require(xxx.php)。

解决办法2
给网站的上级目录赋予iis用户读权限。

posted @ 2010-06-08 10:19 world_eyes 阅读(8775) | 评论 (1)编辑 收藏

经常有朋友在安装某种小软件后,IE主页被篡改,而你在ie选项里改回来后,再打开又时主页又变成了另外一个网址。这说明这个流氓软件在注册表里还 有别的 窠,这些可能位置都有哪些呢?我们根据有限经验,先列出最重要的这几条,期待朋友们补充更多的发现。点击开始-运行-输入regedit回车,依次找到如 下位置——当然,笔者推荐使用Registry Workshop软件,可以直接粘 贴以下地址回车,并将该地址添加到收藏夹,以后旧的不用再找,新的也可见者收藏。

1、internet选项对应的注册表值:

HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMainStart Page

这项的值和ie选项里的主页是同步的,可以先试试。convert swf to avi

2、绑定ie主程序运行参数:

HKEY_CLASSES_ROOTApplicationsiexplore.exeshellopencommand

这项的正常值是”C:Program FilesInternet ExplorerIEXPLORE.EXE” %1,流氓软件将自己的网址附加在后面当作一个运行参数,那么打开ie主程序时就会自动跳转到该网址,这招够狠。

3、 绑定ie窗体控件ieframe.dll主页命令:

HKEY_CLASSES_ROOTCLSID{871C5380-42A0-1069-A2EA-08002B30309D}shellOpenHomePageCommand

这项的默认值是”C:Program FilesInternet Exploreriexplore.exe”,同样,流氓网址可能附加在后面,拦截主页。

4、绑定ie快捷方式运行目标:

还有一种在注册表里无论如何也搜索不到,却远在天边近在眼前的手段,就是修改了ie 快捷方式属性里的运行目标。注意是快捷方式,不是桌面默认显示的ie图标。正常的ie快捷方式有四种

可以看出上面三个ie快捷方式依次是由桌面ie图标创建、由开始菜单顶端ie图标创建、由系统盘ie主程序创建的(当然如果你隐藏了扩展名,第三个 快捷 方式就没有.exe后缀),flv player 第四种是在开始按钮右边快速启动栏上的“启动Internet Explorer”图标。右键查看这些快捷方式属性

笔者快速启动栏已删除启动ie的图标,搁笔追思,远求而来,故上面窗口略显异域。这两个 快捷方式,目标默认值都是”C:Program FilesInternet Exploreriexplore.exe”,这下病毒又有空可钻了,只要把自己的网址追加到后面,那么你经这个图标打开ie时,就会立即跳到它的网 址,真是无所不用其极。

所以笔者建议,如果主页被篡改并改不回来了,请先右键你 启动ie时所打开的快捷方式,看属性“目标”后面有无追加网址,有则删之;不行的话就去注册表里查看那些可能位置:

HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMainStart Page
HKEY_CLASSES_ROOTApplicationsiexplore.exeshellopencommand
HKEY_CLASSES_ROOTCLSID{871C5380-42A0-1069-A2EA-08002B30309D}shellOpenHomePageCommand

看值的后面有没有“尾巴”,这些网址有时可能是乱码,全部剪掉,swf to mov回 复默认值,主页就改回来 了。这样只是暂时堵住,若想彻底杜绝,请先卸载新安装的流氓软件,以后也莫乱逛网站或接受推荐下载安装那些你以为是发现新天地其实可 能早已臭名昭著的小流氓。当然,如果你熟悉了更多的篡改主页伎俩,就不用有这些顾虑了。笔者再次推荐注册表管理软件Registry Workshop,平时多积累自己的 发现,保持“与毒俱进”,将病毒流氓的伎俩尽收囊中。那么以后就可以高枕无忧了。

posted @ 2010-06-04 18:04 world_eyes 阅读(359) | 评论 (0)编辑 收藏

     Tomcat下,不同的二级域名,Session默认是不共享的,因为Cookie名称为JSESSIONID的Cookie根域是默认是没设置的,访问 不同的二级域名,其Cookie就重新生成,而session就是根据这个Cookie来生成的,所以在不同的二级域名下生成的Session也不一样。 找到了其原因,就可根据这个原因对Tomcat在生成Session时进行相应的修改(注:本文针对Tomcat 6.0)。

     单个web项目运行在tomcat上但是却使用多个子域名,如:

 - site.com
 - www.site.com
 - sub1.site.com
 - sub2.site.com
 - etc.

 

这样会导致session的不能共享,在网络上查找的并却最快的解决办法。

 

解决办法:

Usage:
 - compile CrossSubdomainSessionValve & put it in a .jar file
 - put that .jar file in $CATALINA_HOME/lib directory
 - include a <Valve className="org.three3s.valves.CrossSubdomainSessionValve"/> in
$CATALINA_HOME/conf/server.xml

package org.three3s.valves;

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.catalina.*;
import org.apache.catalina.connector.*;
import org.apache.catalina.valves.*;
import org.apache.tomcat.util.buf.*;
import org.apache.tomcat.util.http.*;

/**
 * <p>
 * Replaces the domain of the session cookie generated by Tomcat with a domain
 * that allows that session cookie to be shared across subdomains. This valve
 * digs down into the response headers and replaces the Set-Cookie header for
 * the session cookie, instead of futilely trying to modify an existing Cookie
 * object like the example at 
http://www.esus.be/blog/?p=3. That approach does
 * not work (at least as of Tomcat 6.0.14) because the
 * <code>org.apache.catalina.connector.Response.addCookieInternal</code> method
 * renders the cookie into the Set-Cookie response header immediately, making
 * any subsequent modifying calls on the Cookie object ultimately pointless.
 * </p>
 * 
 * <p>
 * This results in a single, cross-subdomain session cookie on the client that
 * allows the session to be shared across all subdomains. However, see the
 * {
@link getCookieDomain(Request)} method for limits on the subdomains.
 * </p>
 * 
 * <p>
 * Note though, that this approach will fail if the response has already been
 * committed. Thus, this valve forces Tomcat to generate the session cookie and
 * then replaces it before invoking the next valve in the chain. Hopefully this
 * is early enough in the valve-processing chain that the response will not have
 * already been committed. You are advised to define this valve as early as
 * possible in server.xml to ensure that the response has not already been
 * committed when this valve is invoked.
 * </p>
 * 
 * <p>
 * We recommend that you define this valve in server.xml immediately after the
 * Catalina Engine as follows:
 * 
 * <pre>
 * &lt;Engine name=&quot;Catalina&quot;&gt;
 *     &lt;Valve
 * className=&quot;org.three3s.valves.CrossSubdomainSessionValve&quot;/&gt;
 * </pre>
 * 
 * </p>
 
*/
public class CrossSubdomainSessionValve extends ValveBase {
    
public CrossSubdomainSessionValve() {
        
super();
        info 
= "org.three3s.valves.CrossSubdomainSessionValve/1.0";
    }

    @Override
    
public void invoke(Request request, Response response) throws IOException, ServletException {
        
// this will cause Request.doGetSession to create the session cookie if
        
// necessary
        request.getSession(true);

        
// replace any Tomcat-generated session cookies with our own
        Cookie[] cookies = response.getCookies();
        
if (cookies != null) {
            
for (int i = 0; i < cookies.length; i++) {
                Cookie cookie 
= cookies[i];
                
// System.out.println("CrossSubdomainSessionValve: Cookie name is "
                
// + cookie.getName());
                if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) replaceCookie(request, response, cookie);
            }
        }

        
// process the next valve
        getNext().invoke(request, response);
    }

    
/**
     * Replaces the value of the response header used to set the specified
     * cookie to a value with the cookie's domain set to the value returned by
     * <code>getCookieDomain(request)</code>
     * 
     * 
@param request
     * 
@param response
     * 
@param cookie
     *            cookie to be replaced.
     
*/
    
protected void replaceCookie(Request request, Response response, Cookie cookie) {
        
// copy the existing session cookie, but use a different domain
        Cookie newCookie = new Cookie(cookie.getName(), cookie.getValue());
        
// System.out.println("CrossSubdomainSessionValve: CookiePath is " +
        
// cookie.getPath());
        if (cookie.getPath() != null) newCookie.setPath(cookie.getPath());
        String domain 
= getCookieDomain(request);
        
if (!".piaoyoo.com".equals(domain)) domain = request.getServerName();
        
// System.out.println("CrossSubdomainSessionValve: CookieDomain is " +
        
// domain);
        newCookie.setDomain(domain);
        newCookie.setMaxAge(cookie.getMaxAge());
        newCookie.setVersion(cookie.getVersion());
        
// System.out.println("CrossSubdomainSessionValve: CookieComment is " +
        
// cookie.getComment());
        if (cookie.getComment() != null) newCookie.setComment(cookie.getComment());
        newCookie.setSecure(cookie.getSecure());

        
// if the response has already been committed, our replacement strategy
        
// will have no effect
        if (response.isCommitted()) System.out.println("Error CrossSubdomainSessionValve: response was already committed!");

        
// find the Set-Cookie header for the existing cookie and replace its
        
// value with new cookie
        MimeHeaders headers = response.getCoyoteResponse().getMimeHeaders();
        
for (int i = 0, size = headers.size(); i < size; i++) {
            
if (headers.getName(i).equals("Set-Cookie")) {
                MessageBytes value 
= headers.getValue(i);
                
if (value.indexOf(cookie.getName()) >= 0) {
                    StringBuffer buffer 
= new StringBuffer();
                    ServerCookie.appendCookieValue(buffer, newCookie.getVersion(), newCookie.getName(), newCookie.getValue(),
                            newCookie.getPath(), newCookie.getDomain(), newCookie.getComment(), newCookie.getMaxAge(), newCookie
                                    .getSecure());
                    
// System.out.println("CrossSubdomainSessionValve: old Set-Cookie value: "
                    
// + value.toString());
                    
// System.out.println("CrossSubdomainSessionValve: new Set-Cookie value: "
                    
// + buffer);
                    
// System.out.println("-----------------------------");
                    value.setString(buffer.toString());
                }
            }
        }
    }

    
/**
     * Returns the last two parts of the specified request's server name
     * preceded by a dot. Using this as the session cookie's domain allows the
     * session to be shared across subdomains. Note that this implies the
     * session can only be used with domains consisting of two or three parts,
     * according to the domain-matching rules specified in RFC 2109 and RFC
     * 2965.
     * 
     * <p>
     * Examples:
     * </p>
     * <ul>
     * <li>foo.com => .foo.com</li>
     * <li>www.foo.com => .foo.com</li>
     * <li>bar.foo.com => .foo.com</li>
     * <li>abc.bar.foo.com => .foo.com - this means cookie won't work on
     * abc.bar.foo.com!</li>
     * </ul>
     * 
     * 
@param request
     *            provides the server name used to create cookie domain.
     * 
@return the last two parts of the specified request's server name
     *         preceded by a dot.
     
*/
    
protected String getCookieDomain(Request request) {
        String cookieDomain 
= request.getServerName();
        String[] parts 
= cookieDomain.split("\\.");
        
if (parts.length >= 2) cookieDomain = parts[parts.length - 2+ "." + parts[parts.length - 1];
        
return "." + cookieDomain;
    }

    
public String toString() {
        
return ("CrossSubdomainSessionValve[container=" + container.getName() + ']');
    }
}



posted @ 2010-06-04 17:17 world_eyes 阅读(1664) | 评论 (0)编辑 收藏


一台服务器几乎所有网站打开网页 甚至HTML网页 都出现了

<i*f*r*a*m*e src="http://xxx.xx.htm" height=0 width=0></<i*f*r*a*m*e>
这种样式的代码 有的在头部 有的在尾部 部分杀毒软件打开会报毒

打开HTML或ASP PHP页面 在源码中怎么也找不到这段代码

分析原因

首先怀疑ARP挂马,用防ARP的工具又没有发现有arp欺骗

而且arp欺骗一般不会每次都被插入代码,而是时有时无

而且使用http://127.0.0.1 或者http://localhost 访问的时候也可以找到这段代码

arp欺骗的可能排除。

然后就想到可能是JS被篡改,或者是其它的包含文件,查找后没有发现被改的页面 连新建的HTML页面浏览的时候也会被插入这段代码,那就只能是通过IIS挂上去的了。

备份iis数据然后重装iis,代码消失,将备份的iis恢复,问题又来了。


仔细寻找,问题应该出在IIS的配置文件上,打开配置文件,没有发现那段代码。

那很有可能是调用了某个文件,这个怎么查啊,忽然想起了大名鼎鼎的Filemon

本地载了一个上传到服务器上,,打开Filemon,数据太多了,过滤掉一些没有用的

只留下iis的进程,数据还是很多,看来服务器上的站点还是挺多人在访问的。

关掉所有站点,建了一个测试站点anky 目录为D:\www\ 在下面建了一个空白页面test.htm

访问一下这个页面代码被插进来了,再看一下Filemon 奇怪怎么读取C:\Inetpub\wwwroot\iisstart.htm

打开C:\Inetpub\wwwroot\iisstart.htm一看,里面就躺着

<<i*f*r*a*m*e src="http://xx.xxx.jj.htm" height=0 width=0></<i*f*r*a*m*e>

把代码删除了留空,访问test.htm 正常了,把C:\Inetpub\wwwroot\iisstart.htm删除了再访问

test.htm 出现 “读取数据页脚文件出错”问题就出这里了,看来是调用了

这个文件。


把C:\Inetpub\wwwroot\iisstart.htm清空就正常了,这样怎么行,解决问题当然要连根拔掉。

continue

有没有可能是扩展造成的,到扩展中检查了一遍全部都是正常的

当然 通过ISAPI 挂马的也是存在的

左想右想最后还是觉得配置文件有问题

打开配置文件,配置文件在%windir%\system32\inetsrv\Metabase.xml

用记事本打开,查找iisstart.htm 找到一行,开始以为是默认站点,后来一想不对啊

默认站点都删除了,再仔细一看这句代码为

DefaultDocFooter="FILE:C:\Inetpub\wwwroot\iisstart.htm"

删除掉这一行,问题彻底解决了。

==========================================================================
现象:不管是访问服务器上的任何网页,就连404的页面也会在<html>后加入
<<i*f*r*a*m*e SRc=http://xxx.xxx.com/k.htm width=1 height=1 frameborder=0></<i*f*r*a*m*e>,挂马的位置在html标记左右,上面这段恶意代码,它会每隔几秒 加入代码,也就是说在输出具体的东西之前就被挂了,有时有有时又没有,不是网页源代码问题,也没有在网页源代码中加入恶意代码,即使重装服务器,格式化重 分区过第一个硬盘,放上去网站没多久一样再会出现这种情况。


首先就排除了网站被入侵的可能,因为首页能加在那个位置只能是title的地方,用js控制也不大可能.然后去看了php.ini的设置也没有任何的异 常,而且这个插入的代码有的时候出现有的时候不出现,说明不是网站的问题了.打开同服务器的其他网站也有这个情况发生,而且状况一一样.检查并且搜索挂马 的关键字之后确定不是网站程序的问题.

那么剩下的要么是IIS自己出了问题,要么是网络的问题,因为数据是处理没有问题(这个由程序输出,而且即使是html都会出问题),经过一个一个排查, 最后基本可以确定就是arp欺骗欺骗数据报走向,然后中间人修改一些定义的关键字.因为是网络层次有问题(所以重做系统是没有用的).


目的:通过arp欺骗来直接挂马
优点:可以直接通过arp欺骗来挂马.

通常的arp欺骗的攻击方式是在同一vlan下,控制一台主机来监听密码,或者结合ssh中间人攻击来监听ssh1的密码.
但这样存在局限性:
1.管理员经常不登陆,那么要很久才能监听到密码
2.目标主机只开放了80端口,和一个管理端口,且80上只有静态页面,那么很难利用.而管理端口,如果是3389终端,或者是ssh2,那么非常难监听 到密码.

优点:
1.可以不用获得目标主机的权限就可以直接在上面挂马
2.非常隐蔽,不改动任何目标主机的页面或者是配置,在网络传输的过程中间直接插入挂马的语句.
3.可以最大化的利用arp欺骗,从而只要获取一台同一vlan下主机的控制权,就可以最大化战果.


原理:arp中间人攻击,实际上相当于做了一次代理。

正常时候: A---->B ,A是访问的正常客户,B是要攻击的服务器,C是被我们控制的主机
arp中间人攻击时候: A---->C---->B
B---->C---->A
实际上,C在这里做了一次代理的作用

那么HTTP请求发过来的时候,C判断下是哪个客户端发过来的包,转发给B,然后B返回HTTP响应的时候,在HTTP响应包中,插入一段挂马的代码,比 如<爱生活,爱猫扑>...之类,再将修改过的包返回的正常的客户A,就起到了一个挂马的作用.在这个过程中,B是没有任何感觉的,直接攻击 的是正常的客户A,如果A是管理员或者是目标单位,就直接挂上马了.

什么是ARP?

英文原义:Address Resolution Protocol 
中文释义:(RFC-826)地址解析协议 局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。所谓“地址解析”就是主机在
发送帧前将目标IP地址转换成目标MAC地址的过程。ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址以保证通信的顺利进 行。 

注解:简单地说,ARP协议主要负责将局域网中的32为IP地址转换为对应的48位物理地址,即网卡的MAC地址,比如IP地址为192.168.0.1 网卡MAC地址为00-03-0F-FD-1D-2B。整个转换过程是一台主机先向目标主机发送包含IP地址信息的广播数据包,即ARP请求,然后目标主 机向该主机发送一个含有IP地址和MAC地址数据包,通过MAC地址两个主机就可以实现数据传输了。 

应用:在安装了以太网网络适配器的计算机中都有专门的ARP缓存,包含一个或多个表,用于保存IP地址以及经过解析的MAC地址。在Windows中要查 看或者修改ARP缓存中的信息,可以使用arp命令来完成,比如在Windows XP的命令提示符窗口中键入“arp -a”或“arp -g”可以查看ARP缓存中的内容;键入“arp -d IPaddress”表示删除指定的IP地址项(IPaddress表示IP地址)。arp命令的其他用法可以键入“arp /?”查看到。
============================================================================
解决方案如下:

联系机房,用拨网线的排除法,找出同路由内中了类似47555病毒的机器,隔离。杀毒。

其他机器,遇到这种情况,重装系统是没用的。

Asion注:  ARP和挂马 有很深的学问

来源:http://i.mop.com/Noisa/blog/2008/03/13/6264338.html

posted @ 2010-06-04 16:04 world_eyes 阅读(610) | 评论 (0)编辑 收藏

微软关于IE、Firefox、Opera和Safari的JavaScript兼容性研究曾经发表过一份草案,可以点击下载《JScript Deviations from ES3 以下为网上的一些搜集和整理(FF代表Firefox)

 集合类对象问题
现有代码中存在许多 document.form.item("itemName") 这样的语句,不能在 FF 下运行
解决方法:
改用 document.form.elements["elementName"]
说明:IE下,可以使用()或[]获取集合类对象;Firefox下,只能使用[]获取集合类对象.
解决方法:统一使用[]获取集合类对象.


window.event
现有问题:
使用 window.event 无法在 FF 上运行
解决方法:
FF 的 event 只能在事件发生的现场使用,此问题暂无法解决。可以这样变通:
原代码(可在IE中运行):
<input type="button" name="someButton" value="提交" onclick="javascript:gotoSubmit()"/>
<script language="javascript">
    function gotoSubmit() {
       alert(window.event);    // use window.event
    }
</script>

新代码(可在IE和FF中运行):
<input type="button" name="someButton" value="提交" onclick="javascript:gotoSubmit(event)"/>
<script language="javascript">
   function gotoSubmit(e) {
      e = e? e : (window.event ? window.event : null);
      alert(e);           
  }
</script>

此外,如果新代码中第一行不改,与老代码一样的话(即 gotoSubmit 调用没有给参数),则仍然只能在IE中运行,但不会出错。所以,这种方案 tpl 部分仍与老代码兼容。

 

HTML 对象的 id 作为对象名的问题
现有问题:
在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 FF 中不能。
解决方法:
用 getElementById("idName") 代替 idName 作为对象变量使用。

用idName字符串取得对象的问题
现有问题:
在IE中,利用 eval(idName) 可以取得 id 为 idName 的 HTML 对象,在FF 中不能。
解决方法:
用 getElementById(idName) 代替 eval(idName)。

 

变量名与某 HTML 对象 id 相同的问题
现有问题:
在 FF 中,因为对象 id 不作为 HTML 对象的名称,所以可以使用与 HTML 对象 id 相同的变量名,IE 中不能。
解决方法:
在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。
此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误。

 

event.x 与 event.y 问题
现有问题:
在IE 中,event 对象有 x, y 属性,FF中没有。
解决方法:
在FF中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
如果要完全一样,可以稍麻烦些:
mX = event.x ? event.x : event.pageX;
然后用 mX 代替 event.x
其它:
event.layerX 在 IE 与 FF 中都有,具体意义有无差别尚未试验。

 

关于frame
现有问题:
在 IE中 可以用window.testFrame取得该frame,FF中不行
解决方法:
在frame的使用方面FF和ie的最主要的区别是:
如果在frame标签中书写了以下属性:
<frame src="/xx.htm" id="frameId" name="frameName" />
那么ie可以通过id或者name访问这个frame对应的window对象
而FF只可以通过name来访问这个frame对应的window对象
例如如果上述frame标签写在最上层的window里面的htm里面,那么可以这样访问
IE: window.top.frameId或者window.top.frameName来访问这个window对象
FF: 只能这样window.top.frameName来访问这个window对象
另外,在FF和ie中都可以使用window.top.document.getElementById("frameId")来访问frame标签
并且可以通过window.top.document.getElementById("testFrame").src = 'xx.htm'来切换frame的内容
也都可以通过window.top.frameName.location = 'xx.htm'来切换frame的内容

 

父结点的问题
在FF中没有 parentElement parentElement.children  而用 parentNode parentNode.childNodes
childNodes的下标的含义在IE和FF中不同,FF使用DOM规范,childNodes中会插入空白文本节点。
一般可以通过node.getElementsByTagName()来回避这个问题。当html中节点缺失时,IE和FF对parentNode的解释不同,例如
<form>
<table>
  <input/>
</table>
</form>

FF中input.parentNode的值为form, 而IE中input.parentNode的值为空节点
FF中节点没有removeNode方法,必须使用如下方法 node.parentNode.removeChild(node)

 

const 问题
现有问题:
在 IE 中不能使用 const 关键字。如 const constVar = 32; 在IE中这是语法错误。
解决方法:
不使用 const ,以 var 代替。

body 对象
FF的body在body标签没有被浏览器完全读入之前就存在,而IE则必须在body完全被读入之后才存在

 

URLencoding
在js中如果书写url就直接写&不要写&例如var url = 'xx.jsp?objectName=xx&objectEvent=xxx';
frm.action = url那么很有可能url不会被正常显示以至于参数没有正确的传到服务器
一般会服务器报错参数没有找到
当然如果是在tpl中例外,因为tpl中符合xml规范,要求&书写为&
一般FF无法识别js中的&

 

nodeName 和 tagName 问题
现有问题:
在FF中,所有节点均有 nodeName 值,但 textNode 没有 tagName 值。在 IE 中,nodeName 的使用好象有问题
解决方法:
使用 tagName,但应检测其是否为空。

 

元素属性
IE下 input.type属性为只读,但是FF下可以修改
document.getElementsByName() 和 document.all[name] 的问题
在 IE 中,getElementsByName()、document.all[name] 均不能用来取得多个具有相同name的div 元素集合。

 

兼容firefox的 outerHTML,FF中没有outerHtml的方法

if (window.HTMLElement) {
  HTMLElement.prototype.__defineSetter__("outerHTML",function(sHTML) {
        var r=this.ownerDocument.createRange();
        r.setStartBefore(this);
        var df=r.createContextualFragment(sHTML);
        this.parentNode.replaceChild(df,this);
        return sHTML;
    });

    HTMLElement.prototype.__defineGetter__("outerHTML",function() {
        var attr;
        var attrs=this.attributes;
        var str="<"+this.tagName.toLowerCase();
        for (var i=0;i<attrs.length;i++) {
            attr=attrs[i];
            if(attr.specified)
                str+=" "+attr.name+'="'+attr.value+'"';
        }

        if(!this.canHaveChildren)
            return str+">";
        return str+">"+this.innerHTML+"</"+this.tagName.toLowerCase()+">";
        });

   HTMLElement.prototype.__defineGetter__("canHaveChildren",function() {
     switch(this.tagName.toLowerCase()) {
         case "area":
         case "base":
         case "basefont":
         case "col":
         case "frame":
         case "hr":
         case "img":
         case "br":
         case "input":
         case "isindex":
         case "link":
         case "meta":
         case "param":
         return false;
     }
     return true;
   });
}


自定义属性问题
说明:IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性;FF下,只能使用getAttribute()获取自定义属性.
解决方法:统一通过getAttribute()获取自定义属性.

 
event.srcElement问题
说明:IE下,even对象有srcElement属性,但是没有target属性;Firefox下,even对象有target属性,但是没有srcElement属性.
解决方法:使用obj(obj = event.srcElement ? event.srcElement : event.target;)来代替IE下的event.srcElement或者Firefox下的event.target.


window.location.href问题
说明:IE或者Firefox2.0.x下,可以使用window.location或window.location.href;Firefox1.5.x下,只能使用window.location.
解决方法:使用window.location来代替window.location.href.


模态和非模态窗口问题
说明:IE下,可以通过showModalDialog和showModelessDialog打开模态和非模态窗口;Firefox下则不能.
解决方法:直接使用window.open(pageURL,name,parameters)方式打开新窗口
如果需要将子窗口中的参数传递回父窗口,可以在子窗口中使用window.opener来访问父窗口. 例如:var parWin = window.opener; parWin.document.getElementById("Aqing").value = "Aqing";

 

事件委托方法
IE:document.body.onload = inject; //Function inject()在这之前已被实现
FF:document.body.onload = inject();
如果要加传递参数,可以做个闭包
(function(arg){

   document.body.onload=function(){inject(arg);};

})(arg)

innerText在IE中能正常工作,但是innerText在FireFox中却不行.
解决方法:
if(navigator.appName.indexOf("Explorer") > -1){
    document.getElementById('element').innerText = "my text";
} else{
    document.getElementById('element').textContent = "my text";
}


FF中类似 obj.style.height = imgObj.height 的语句无效
解决方法:
obj.style.height = imgObj.height + 'px';


IE,FF以及其它浏览器对于 table 标签的操作都各不相同,在ie中不允许对table和tr的innerHTML赋值,使用js增加一个tr时,使用appendChile方法也不管用
解决方法:
//向table追加一个空行:
var row = otable.insertRow(-1);
var cell = document.createElement("td");
cell.innerHTML = " ";
cell.className = "XXXX";
row.appendChild(cell);


样式部分
-----------------------------------------------------------------------------------------------------------
cursor:hand VS cursor:pointer
FF不支持hand,但ie支持pointer
解决方法: 统一使用pointer

padding 问题
padding 5px 4px 3px 1px FireFox无法解释简写,
必须改成 padding-top:5px; padding-right:4px; padding-bottom:3px; padding-left:1px;

消除ulol等列表的缩进时
样式应写成:list-style:none;margin:0px;padding:0px;
其中margin属性对IE有效,padding属性对FireFox有效

CSS透明
IE:filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=60)
FF:opacity:0.6

CSS圆角
IE:不支持圆角
FF: -moz-border-radius:4px,或者-moz-border-radius-topleft:4px;-moz-border- radius-topright:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius- bottomright:4px;

CSS双线凹凸边框
IE:border:2px outset;
FF: -moz-border-top-colors: #d4d0c8 white;-moz-border-left-colors: #d4d0c8 white;-moz-border-right-colors:#404040 #808080;-moz-border-bottom-colors:#404040 #808080;

posted @ 2009-04-11 18:25 world_eyes 阅读(203) | 评论 (0)编辑 收藏