[转载]微信公众号支付开发遇到的几个问题 - 南山北缘 - 博客园

mikel阅读(705)

来源: [转载]微信公众号支付开发遇到的几个问题 – 南山北缘 – 博客园

1.调用统一下单接口验签失败

https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1

开始的时候是string Format格式填写参数,错。后来翻看其他博客和微信demo,才得知应该这样写:

复制代码
//将数据添加到字典中
SortedDictionary<string, string> m_values = new SortedDictionary<string, string>();
            m_values.Add("appid", appID);
            m_values.Add("body", bodymsg);
            m_values.Add("mch_id", mch_id);
            m_values.Add("nonce_str", nonce_str);
            m_values.Add("notify_url", notify_url);
            m_values.Add("openid", openID);
            m_values.Add("out_trade_no", orderId);
            m_values.Add("spbill_create_ip", spbill_create_ip);
            m_values.Add("total_fee", total_fee.ToString());
            m_values.Add("trade_type", "JSAPI");
            string signkey = WXDes.TotUrl(m_values); //拼接数据
复制代码
复制代码
//拼接字符串key=value
  public static string TotUrl(SortedDictionary<string, string> m_values)
        {
            int i = 0;
            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair<string, string> temp in m_values)
            {
                if (temp.Value == "" || temp.Value == null || temp.Key.ToLower() == "sign")
                {
                    continue;
                }
                i++;
                sb.Append(temp.Key.Trim() + "=" + temp.Value.Trim() + "&");
            }
            sb.Append("key=" + ConfigHelp.APISign);
            string signkey = sb.ToString();
            return signkey;
        }
复制代码

2.调用统一下单 body编码问题

刚开始编写是直接body=”你好”直接赋值的,但是微信返回码说没有UTF-8编码,然后又HttpUtility.UrlEncode(“会员 充值”, Encoding.GetEncoding(“UTF-8”)),结果支付页面显示编码后的文字,然后看到帖子说直接赋值就ok,又一直,果真!!!!

body=”直接赋值”

3.API输入密码框页面无法显示

拿到微信返回的prepay_id,访问API接口,是将生成的json返回到前端,alert(json字符串)没有任何问题,传入微信就报缺少参数,几经周折

如此将返回json转换一下 JSON.parse(json)

[转载]apk获得Android系统权限的方法 - ...平..淡... - 博客园

mikel阅读(924)

来源: [转载]apk获得Android系统权限的方法 – …平..淡… – 博客园

想写一个重启系统的apk(reboot.apk),因为没有权限,所以编译出来的apk无法达到效果。

网上查到的方法讲的不太清楚,至少我是这么觉得,因为我照着做,试了好多次才成功。下面是我尝试过并成功的两个方法,总结如下。

 

方法1:通过将项目作为一个模块,放到Android系统源码中进行编译~~~

步骤如下:

1. 在应用程序的AndroidManifest.xml中的manifest节点中加入”Android:sharedUserId=”android.uid.system”这个属性。

复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  ……
android:sharedUserId="android.uid.system" >  <!--添加该属性-->
    
<uses-permission android:name="android.permission.SHUTDOWN"/> <!--添加该权限-->
……
</manifest>
复制代码

ps:android:sharedUserId=”android.uid.system” 将app提升到系统权限,需要到源码中编译;还有关机权限:android.permission.SHUTDOWN

2.编译apk

(1)将应用程序的src文件、res文件和AndroidManifest.xml文件拷贝到Android系统源码package/apps目录下

(2)编写一个Android.mk文件(最简单的方法就是拷贝其他模块中的Android.mk文件),修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行

Android.mk:

复制代码
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_PACKAGE_NAME := 你的项目名
LOCAL_CERTIFICATE := platform    #添加这一句

include $(BUILD_PACKAGE)
复制代码

 

(3)mm 编译,生成apk

总结:其实就是把应用程序当作系统应用进行编译~~这样之后就会有系统权限了。

 

方法2:这个办法麻烦点,不过不用跑到源码环境下用make来编译:

步骤:

1. 同上,加入android:sharedUserId=”android.uid.system”这个属性。

2. 使用eclipse编译出apk文件,但是这个apk文件是不能用的。

3. 用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。

4. 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,

(4.1)首先找到密钥文件。是”build/target/product/security”路径下的platform.pk8和platform.x509.pem两个文件。

(4.2)然后用Android提供的Signapk工具(即signapk.jar)来签名。signapk的源代码是在”build/tools/signapk”下。

(4.3)进入”build/tools/signapk”目录下(接下来一直在该目录下进行以下指令)

复制代码
1.javac Signapk.java  //编译生成SignApk$SignatureOutputStream.class和SignApk.class文件,将这两个文件拷贝到新创建的com/android/signapk目录下。
2.jar cvfm signapk.jar SignApk.mf com //JAR命令使用中有解释
3.将reboot.apk、platform.pk8、platform.x509.pem文件复制到"build/tools/signapk"目录下,然后执行下面指令。
4.java -jar signapk.jar platform.x509.pem platform.pk8 reboot.apk reboot_signed.apk //生成了reboot_signed.apk,这个就是最终想要的apk了
复制代码

 

ps1:如果源码全编译过,那就已经生成了signapk.jar文件,可以直接拷贝过来,路径在/out/host /linux-x86/framework/signapk.jar。当然,要是没有环境全编译源码,但又需要signapk.jar文件,就可以通过以 上方法来获得。打包生成signapk.jar文件可以重用,不用每次都重新打包。

ps2:key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才 真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因 为这样的系统才可以拿到 platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。

[转载]Android 模拟系统事件(一) - banketree - 博客频道 - CSDN.NET

mikel阅读(1045)

来源: [转载]Android 模拟系统事件(一) – banketree – 博客频道 – CSDN.NET

目录(?)[+]

简介

Android系统是在Linux 2.6版本上开发的,所以起使用设备驱动  /dev/input/event  X (x为0到7)分别来映射不同事件。

内容

这里就简单介绍两种系统自带类来实现系统事件注入。

方式一:

需要使用的类如下:

  1. Android.os.ServiceManager
  2. Android.view.IWindowManager

很不幸,笔者在引用他的使用,发现已经被隐藏了,经过查阅资料,有两种方法可引用。
1、在项目中创建对应路径的包和类,然后引用,如下:

  1. package android.os;
  2. import android.os.IBinder;
  3. public class ServiceManager {
  4.     public static IBinder getService(String serviceName) {
  5.         return null;
  6.     }
  7. }
  1. package android.view;
  2. import android.os.IBinder;
  3. import android.view.KeyEvent;
  4. import android.view.MotionEvent;
  5. public interface IWindowManager {
  6.     public static class Stub {
  7.         public static IWindowManager asInterface(IBinder binder) {
  8.             return null;
  9.         }
  10.     }
  11.     // 注入自己的窗口事件
  12.     public boolean injectKeyEvent(KeyEvent ev, boolean sync);
  13.     public boolean injectPointerEvent(MotionEvent ev, boolean sync);
  14.     public boolean injectTrackballEvent(MotionEvent ev, boolean sync);
  15.     // public boolean injectInputEventNoWait(InputEvent ev);
  16. }

2、载入类,添加代码替换原来的实现方法。

  1. try{
  2.   Object object = new Object();
  3.   Method getService = Class.forName(“android.os.ServiceManager”).getMethod(“getService”, String.class);
  4.   Object obj = getService.invoke(object, new Object[]{new String(“window”)});
  5.   //System.out.println(obj.toString());
  6.   windowMger = IWindowManager.Stub.asInterface((IBinder)obj);
  7.   }catch(Exception ex){
  8.   }

方式二:

需要使用的类如下:

  1. android.app.Instrumentation

Instrumentation是Android 测试环境的一个核心框架,在这个框架下,你的测试应用程序可以精确控制应用程序。使用Instrumentation,你可以在主程序启动之前,创建模拟 的系统对象,如Context;控制应用程序的多个生命周期;发送UI事件给应用程序;在执行期间检查程序状态。 Instrumentation框架通 过将主程序和测试程序运行在同一个进程来实现这些功能。

测试如下:

  1. Instrumentation m_Instrumentation = new Instrumentation();
  2. m_Instrumentation
  3.         .sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);

注意:以上方法只能用于本程序,用于其它程序会包INJECT_EVENTS权限不够错误,但笔者添加了INJECT_EVENTS权限,没有起到作用。

  1. <uses-permission android:name=“android.permission.INJECT_EVENTS” />
  2. //允许一个程序截获用户事件如按键、触摸、轨迹球等等到一个时间流,android 开发网提醒算是hook技术吧

那么如何突破INJECT_EVENTS权限问题?方法有两:

一、将你的程序或服务改成系统级别的,在manifest加如下代码:

  1. <manifest xmlns:android=“http://schemas.android.com/apk/res/android”
  2.     package=“com.banketree.testinjectorandroid”
  3.     android:versionCode=“1”
  4.     android:versionName=“1.0”
  5.     android:sharedUserId=“android.uid.system” >

然后源文件添加到添加Android.mk文件,重新编译源码。

二、通过jni的方法将kernel 的发送keyevent的方法用NDK封装成方法,做成库给java调用,封装事件写入jni,然后Java调用,从而不必通过Android WindowsManagerService的验证,具体如何实现,后期贴出。

结束

简单的介绍了向系统注入事件的两种方法,该两种方法都可以达到功能要求,但仅能在原生程序中执行。

项目下载

[MySQL]快速解决"is marked as crashed and should be repaired"故障

mikel阅读(751)

具体报错如下:

Table ‘.\Tablename\posts’ is marked as crashed and should be repaired

提示说论坛的帖子表posts被标记有问题,需要修复。我记得以前也出现过类似的问题,但是只要点击Phpmyadmin上的repair按纽就自动修复了,但是这次很绝,什么都没有.于是赶快上网查找原因。最终将问题解决。解决方法如下:

找到mySQL的安装目录的bin/myisamchk工具,在命令行中输入:

myisamchk -c -r ../data/tablename/posts.MYI

然后myisamchk 工具会帮助你恢复数据表的索引。好象也不用重新启动mySQL,问题就解决了。

问题分析:

1、
错误产生原因,有网友说是频繁查询和更新dede_archives表造成的索引错误,因为我的页面没有静态生成,而是动态页面,因此比较同意这种说法。
还有说法为是MYSQL数据库因为某种原因而受到了损坏,如:数据库服务器突发性的断电、在提在数据库表提供服务时对表的原文件进行某种操作都有可能导致
MYSQL数据库表被损坏而无法读取数据。总之就是因为某些不可测的问题造成表的损坏。

2、问题解决办法。

当你试图修复一个被破坏的表的问题时,有三种修复类型。如果你得到一个错误信息指出一个临时文件不能建立,删除信息所指出的文件并再试一次–这通常是上一次修复操作遗留下来的。
这三种修复方法如下所示:
% myisamchk –recover –quick /path/to/tblName
% myisamchk –recover /path/to/tblName
% myisamchk –safe-recover /path/to/tblName

第一种是最快的,用来修复最普通的问题;而最后一种是最慢的,用来修复一些其它方法所不能修复的问题。

检查和修复MySQL数据文件
如果上面的方法无法修复一个被损坏的表,在你放弃之前,你还可以试试下面这两个技巧:

果你怀疑表的索引文件(*.MYI)发生了不可修复的错误,甚至是丢失了这个文件,你可以使用数据文件(*.MYD)和数据格式文件(*.frm)重新生
成它。首先制作一个数据文件(tblName.MYD)的拷贝。重启你的MySQL服务并连接到这个服务上,使用下面的命令删除表的内容:
mysql> DELETE FROM tblName;

删除表的内容的同时,会建立一个新的索引文件。退出登录并重新关闭服务,然后用你刚才保存的数据文件(tblName.MYD)覆盖新的(空)数据文件。
最后,使用myisamchk执行标准的修复(上面的第二种方法),根据表的数据的内容和表的格式文件重新生成索引数据。

如果你的表的
格式文件(tblName.frm)丢失了或者是发生了不可修复的错误,但是你清楚如何使用相应的CREATE
TABLE语句来重新生成这张表,你可以重新生成一个新的.frm文件并和你的数据文件和索引文件(如果索引文件有问题,使用上面的方法重建一个新的)一
起使用。首先制作一个数据和索引文件的拷贝,然后删除原来的文件(删除数据目录下有关这个表的所有记录)。

启动MySQL服务并使用当初的CREATE TABLE文件建立一个新的表。新的.frm文件应该可以正常工作了,但是最好你还是执行一下标准的修复(上面的第二种方法)。

 

 

为了不冒失修复,故采取保守做法,我们知道 MySQL 一个高效的管理工具便是 PhpMyAdmin,而在该管理软件中就包含了对表的检查、分析、修复、优化功能,比起网上提供的含糊命令行来说更安全更简便。

image

通过实践,在使用检查表功能后确实发现了问题,之后使用修复功能进行了修复,反馈结果每个表都已经 ok,再执行一次优化,重新测试访问网站终于恢复了正常。一场灾难就此避免……

[转载]《把时间当作朋友》——介绍几个十分有效的时间管理工具 - cotyb - 博客园

mikel阅读(882)

来源: [转载]《把时间当作朋友》——介绍几个十分有效的时间管理工具 – cotyb – 博客园

原文发表在我的博客主页,转载请注明出处。
这是寒假期间读的一本书,拿到书之后读了前面几节便欲罢不能,因为书中列举的很多实例确实很符合我的情况,所以匆匆读完了此书,总体感觉是前面内容比较 好,让我有了一些思考,后面的章节却难免落入了俗套,不过看了之后肯定是有一些收获的,个人给7/10分,个人觉得,看一本书如果能让我想明白一个道理, 或者自己有一点进步就好,这本书做到了,对兴趣的谈论让我茅塞顿开。下面直接上图,有兴趣的可以自己阅读,本博客主要还是介绍几个时间管理软件的。

时间管理工具介绍:

  • Windows:在Windows系统下我主要使用三个工具:桌面便签;映象笔记;OneNote,各自有各自的用途和优缺点,所以我的使用习惯如下:
    桌边便签:有事情、感想、任务、todo了随时记录在桌面,可以时时进行查看,而且可以将一些工具的快捷键,一些容易忘掉的命令,还有接下来要做的事情列 出来,可以毫无逻辑,毫无章法,想创建一个新的便签就创建,充分体现了灵活和简洁性,对于时间规划来说,一般会记录短期要完成的,比较紧迫同时比较具体的 任务,但是他直接出现在桌面,隐私性不大好,下图就是我的桌面(囧~)

    印象笔记:个人感觉现在国内的为知笔记可以完全碾压印象笔记了,但是由于用的早,养成习惯了,前面还汇总了使用markdown编辑印象笔记的常用方法,所以怒其不争却放不开手,印象笔记主要是记录知识点,构建自己的知识框架,我还用他做一些工作log的记录
    OneNote:这个主要是做长远的规划用的,比如月计划,年计划,而且计划的内容不具体,比较general,和桌面便签互补,记录一些较私密的东西
  • ipad:主要有三个工具:myweek,Kanbana,Countdown
    myweek格式类似于google日历,界面以及时间管理思路非常接近,所以可以传承习惯
    kanbana是十分推荐的一款软件,他的管理思路是我一直比较崇尚的,所以看到他之后便爱不释手,附图:

    Countdown是记录一些重要日期的,比如和女票在一起的多少天。。。(害羞)
  • Android手机:主要有TickTick,系统便签,Pomotodo,再加上系统的日历
    最推荐的当属TickTick,界面十分美观,直接上图。每天早晨起来的第一件事情就是看这个东西,看今天,接下来几天需要做哪些事情,十分好用。

    很多时候,我们可能不在PC跟前,所以和桌面便签类似的便是手机系统便签,随时记,随时想
    Pomotodo这个是番茄时间管理软件,如果你精力容易分散,经常干着干着就开始浏览网页,刷博客园,刷知乎,强烈推荐,可以使精神高度集中的干一件事情
    日历:记录好友的生日,一些太重要的事情提供提醒
不向静中参妙理,纵然颖悟也虚浮 立乎其大 和而不同 古之成大事者,不惟有超世之才,亦必有坚韧不拔之志

[转载]Android开发代码规范 - zhuyuliang - 博客园

mikel阅读(1205)

来源: [转载]Android开发代码规范 – zhuyuliang – 博客园

目录

  • 1.命名基本原则 
  • 2.命名基本规范
  • 2.1编程基本命名规范
  • 2.2分类命名规范
  • 3.分类命名规范
  • 3.1基本数据类型命名规范
  • 3.2控件命名规范
  • 3.3变量命名规范
  • 3.4整个项目的目录规范化
  • 3.4 res资源文件命名规范
  • 4.代码书写规范 
  • 5.注释
  • 6.提高代码质量
  • 7.设计模式(Design Patterns)

 

1.命名基本原则
在面向对象编程中,对于类,对象,方法,变量等方面的命名是非常有技巧的。比如,大小写的区分,使用不同字母开头等等。但究其本,追其源,在为一个资源其名称的时候,应该本着描述性以及唯一性这两大特征来命名,才能保证资源之间不冲突,并且每一个都便于记忆。

对于理解应用程序的逻辑流,命名方案是最有影响力的一种帮助。名称应该说明“什么”而不是“如何”。命名原则是:使名称足够长以便有一定的意义,并且足够短以避免冗长。唯一名称在编程上仅用于将各项区分开。以下几点是规范的命名方法。
2.命名基本规范

2.1编程基本命名规范
(1)避免难懂的名称,如属性名xxK8,这样的名称会导致多义性。
(2) 在面向对象的语言中,在类属性的名称中包含类名是多余的,如Book.BookTitle,而是应该使用Book.Title。
(3)在允许函数重载的语言中,所有重载都应该执行相似的函数。

(4)使用动词-名词的方法来命名对给定对象执行特定操作的例程,如CalculateInvoiceTotal()。(例程是某个系统对外提供的功能接口或服务的集合)

(5)只要合适,在变量名的末尾或开头加计算限定符(Avg、Sum、Min、Max、Index)。
(6)在变量名中使用互补对,如min/max、begin/end和open/close。

(7)布尔变量名应该包含Is,这意味着Yes/No 或 True/False 值,如 fileIsFound。

(8)即使对于可能仅出现在几个代码行中的生存期很短的变量,仍然使用有意义的名  称。仅对于短循环索引使用单字母变量名,如 i 或 j。

(9)为了帮助区分变量和例程,对例程名称使用Pascal大小写处理 (CalculateInvoiceTotal),其中每个单词的 第        一个字母都是大写的。对于变量名,使用 camel大小写处理 (documentFormatType),其中除了第一个单词外每个 单词的第一个字母都是大写的。

(10)不要使用原义数字或原义字符串,而是使用命名常数,NUM_DAYS_IN_WEEK ,以便于维护和理解。

 

 

 2.2分类命名规范

(1)包的命名

Java包的名字都是由小写单词组成。但是由于Java面向对象编程的特性,每一名Java程序员都可以编写属于自己的Java包,为了保障每 个Java包命名的唯一性,在最新的Java编程规范中,要求程序员在自己定义的包的名称之前加上唯一的前缀。由于互联网上的域名称是不会重复的,所以程 序员一般采用自己在互联网上的域名称作为自己程序包的唯一前缀。

例如: com.pccb.app

(2)类的命名

类的名字必须由大写字母开头而单词中的其他字母均为小写;如果类名称由多个单词组成,则每个单词的首字母均应为大写例如TestPage;如 果类名称中包含单词缩写,则这个所写词的每个字母均应大写,如:XMLExample,还有一点命名技巧就是由于类是设计用来代表对象的,所以在命名类时 应尽量选择名词。

例如: Circle

(3)方法的命名

方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头。

例如: sendMessge

(4)常量的命名

常量的名字应该都使用大写字母,并且指出该常量完整含义。如果一个常量名称由多个单词组成,则应该用下划线来分割这些单词。

例如: MAX_VALUE

(5)参数的命名

参数的命名规范和方法的命名规范相同,而且为了避免阅读程序时造成迷惑,请在尽量保证参数名称为一个单词的情况下使参数的命名尽可能明确。

私有属性:private int mAge;

静态变量:static String sName;

函数内部变量:int  _Age;

方法定义时的形参:int pAge;

 

(6)Javadoc注释

Java除了可以采用我们常见的注释方式之外,Java语言规范还定义了一种特殊的注释,也就是我们所说的Javadoc注释,它是用来记录我 们代码中的API的。Javadoc注释是一种多行注释,以/**开头,而以*/结束,注释可以包含一些HTML标记符和专门的关键词。使用 Javadoc注释的好处是编写的注释可以被自动转为在线文档,省去了单独编写程序文档的麻烦。

例如:

/**

* This is an example of

* Javadoc

*

* @author darchon

* @version 0.1, 10/11/2002

*/

在每个程序的最开始部分,一般都用Javadoc注释对程序的总体描述以及版权信息,之后在主程序中可以为每个类、接口、方法、字段添加 Javadoc注释,每个注释的开头部分先用一句话概括该类、接口、方法、字段所完成的功能,这句话应单独占据一行以突出其概括作用,在这句话后面可以跟 随更加详细的描述段落。在描述性段落之后还可以跟随一些以Javadoc注释标签开头的特殊段落,例如上面例子中的@auther和@version,这 些段落将在生成文档中以特定方式显示。

虽然为一个设计低劣的程序添加注释不会使其变成好的程序,但是如果按照编程规范编写程序并且为程序添加良好的注释却可以帮助你编写出设计完美,运行 效率高且易于理解的程序,尤其是在多人合作完成同一项目时编程规范就变得更加重要。俗话说“磨刀不误砍柴工”,花费一点时间去适应一下Java编程规范是 有好处的。

 

3.分类命名规范

3.1基本数据类型命名规范

Integer:int+描述          Char:chr+描述          Boolean:bln+描述

Long:lng+描述           Short:shr +描述         Double:dbl+描述

String:str+描述           Float:flt+描述          Single:sng+描述

DataTime:dt+描述         Array:arr+描述        Object:obj+描述

如:String  srtName;

 

3.2控件命名规范 

TextView :txt_+描述 Button :btn_+描述
ImageButton :imgBtn_+描述 ImageView :imgView_+描述
CheckBox :chk_+描述 RadioButton :rdoBtn_+描述
AnalogClock :anaClk_+描述 DigitalClock :DgtClk_+描述
DatePicker :dtPk_+描述 TimePicker :tmPk _+描述
ToggleButton :tglBtn_+描述 EditText:edtTxt_+描述
ProgressBar:lcb_+描述 SeekBar:skBar _+描述
AutoCompleteTextView:autoTxt_+描述 MultiAutoCompleteTextView:mlAutoTxt_+描述
ZoomControls:zmCtrl_+描述 Include:ind_+描述
VideoView:vdoVi_+描述 WebView:webVi_+描述
RatingBar:ratBar_+描述 Tab:tab__+描述
Spinner:spn_+描述 Chronometer:Cmt_+描述
ScrollView:sclVi_+描述 TextSwitcher:txtSwt_+描述
Gallery:gal_+描述 ImageSwitcher:imgSwt_+描述
GridView:gV_+描述 ListView:lVi_+描述
ExpandableList: epdLt_+描述 MapView: mapVi_+描述

 

控件说明如下:

• TextView – 文本显示控件

• Button – 按钮控件

• ImageButton – 图片按钮控件

• ImageView – 图片显示控件

• CheckBox – 复选框控件

• RadioButton – 单选框控件

• AnalogClock – 钟表(带表盘的那种)控件

• DigitalClock – 电子表控件

• DatePicker – 日期选择控件

• TimePicker – 时间选择控件

• ToggleButton – 双状态按钮控件

• EditText – 可编辑文本控件

• ProgressBar – 进度条控件

• SeekBar – 可拖动的进度条控件

• AutoCompleteTextView – 支持自动完成功能的可编辑文本控件

• MultiAutoCompleteTextView – 支持自动完成功能的可编辑文本控件,允许输入多值(多值之间会自动地用指定的分隔符    分开)

• ZoomControls – 放大/缩小按钮控件

• Include – 整合控件

• VideoView – 视频播放控件

• WebView – 浏览器控件

• RatingBar – 评分控件

• Tab – 选项卡控件

• Spinner – 下拉框控件

• Chronometer – 计时器控件

• ScrollView – 滚动条控件

• TextSwitcher – 文字转换器控件(改变文字时增加一些动画效果)

• Gallery –画廊控件

• ImageSwitcher – 图片转换器控件(改变图片时增加一些动画效果)

• GridView – 网格控件

• ListView – 列表控件

• ExpandableList – 支持展开/收缩功能的列表控件

 

3.3变量命名规范

变量命名:前缀+类型描述+意义描述

前缀:

成员变量:m_***             局部变量:l_***          形参:a_***

常量:大写_***                  枚举值:em_***

 

3.4整个项目的目录规范化

1、系统目录规范:

指项目目录中不仅包括源代码,还需要包括:需求相关文档、设计文档、计划日志文档、测试文档、项目进行中学习资料文档(参考Demo);使整个项目更加清晰,

2、源代码目录规范:

一般系统命名空间目录尽量不要超过3层,[组织名].[项目名].[模块名]:com.pccb.app

 

3.5 res资源文件命名

1,res/layout下的xml文件统一用小写和下划线”_”组合命名,并加上前缀以便区分

正例:

对话框的xml配置文件:dlg_name.xml

2.layout中的id采用以下命名模式: view缩写_模块名称_view的逻辑名称

说明:view的缩写详情如下

ListView: lv

RelativeView: rv

TextView: tv

ImageView: iv

ImageButton: ib  / ibtn

Button:  btn

正例:

@+id/lv_appstore_applist

反例:

@+id/ListView01

3.activity文中的view变量采用以下命名模式: 逻辑名称_view缩写

正例:

ListViewapplistLv

4.res/drawable下的资源文件采用以下命名模式:  activity名称_逻辑名称/common_逻辑名称

正例:

main_default.png,main_pressed.png

5.strings.xml中的id采用以下命名模式: activity名称_功能模块名称_逻辑名称/activity名称_逻辑名称/common_逻辑名称

正例:

<string name=”main_downloading”>正在下载„</string>

6.字符串信息应统一在strings.xml中定义,调试信息除外

7.使用日志时,不重要的信息定义在Debug等级或者info等级,较为严重的情况把日志定义的warn等级和error等级。正常情况下尽量不使用System.out.println();作为日志的输出
4.代码书写规范 
(1)建立标准的缩进大小(如四个空格),并一致地使用此标准。用规定的缩进对齐代码节。
(2)在括号对对齐的位置垂直对齐左括号和右括号,如:
for   (i=0; i<100; i++)
{
;
}
(3)沿逻辑结构行缩进代码使代码更易于阅读和理解,如:
if(expression)
{
if(expression )
{
//
//此处填写你的代码块;
//
}
else
{
//
//此处填写你的代码块;
//
}
}
(4)为注释和代码建立最大的行长度,以避免不得不滚动源代码编辑器,并且可以提供整齐的硬拷贝表示形式。
(5)当一行内容太长而必须换行时,在后面换行代码中要使用缩进格式,如下:
string   inserString =”Insert   Into   TableName(username,password,email,sex,address) ”
+”Values( ‘Soholife ‘, ‘chenyp ‘, ‘soholife@sina.com ‘, ‘male ‘, ‘深圳福田 ‘) “;
(6)每一行上放置的语句避免超过一条。特殊循环如for(i =0;i<100;i++)等除外。
(7)编写SQL语句时,对于关键字使用全部大写,对于数据库元素(如表、列和视图)使用大小写混合。例如SELECT * FROM Table1;
(8)将每个主要的SQL子句放在不同的行上,这样更容易阅读和编辑语句,例如:

SELECT   FirstName,   LastName
FROM     Customers
WHERE   State   =   ‘WA ‘

(10)使用空白为源代码提供结构线索。这样做会创建代码“段”,有助于读者理解软件的逻辑分段
(11)将大的复杂代码段分为较小的、易于理解的模块。

5.注释 
软件文档以两种形式存在:外部的和内部的。外部文档(如规范、帮助文件和设计文档)在源代码的外部维护。内部文档由开发人员在开发时在源代码中编写的注释组成。
不考虑外部文档的可用性,由于硬拷贝文档可能会放错地方,源代码清单应该能够独立存在。外部文档应该由规范、设计文档、更改请求、错误历史记录和使用的编码标准组成。   以下几点是规范的注释方法:

(1)一个工程应有一个统一的头文件注释,以说明整个工程的信息、创建日期、版本等等

(2)对重要的程序加注释进行说明

(3)修改代码或删除时,将原代码用注释的方法屏蔽,同时要加开发者自身对修改操作的注释。格式为:

//原代码

//Added/(Modified/ Deleted) by 开发者姓名 年-月-日;

//因为业务原因修改的,要注明修改或删除原因)

新代码
(4)使用XML文档格式,如下面方法的注释:
<!– 注释内容 –>

(5)避免杂乱的注释,而是应该使用空白将注释同代码分开。
(6)移除所有临时或无关的注释,以避免在日后的维护工作中产生混乱。
(7)注释应对代码进行准确的说明,不应存在歧义。
(8)在整个应用程序中,使用具有一致的标点和结构的统一样式来构造注释。

(9)方法注释的内容(1,5,6,7项正常情况下都要写上去)

1.类该方法是做什么的。 2.该方法如何工作。 3.代码修改历史纪录。 4.方法调用代码示范。

5.必须传入什么样的参数给这个方法。@param 6.异常处理。@throws

7.这个方法返回什么。@return

 

6.提高代码质量

(1)删除无用的变量

(2)删除无用的引入

(3)对于可以复用的部分,一定提取成共用的方法,减少代码量

(4)变量/方法命名一定要符合清晰易懂,不用太在乎长度

(5)代码完成后,进行code review,减少出错几率

 (6)  用适合的方式尽量去思考设计模式方式来进行开发

 

 

7.设计模式(Design Patterns)——可复用面向对象软件的基础

   设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用 设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化, 设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每 一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。

   一个程序员对设计模式的理解:
“不懂”为什么要把很简单的东西搞得那么复杂。后来随着软件开发经验的增加才开始明白我所 看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式,目的仅仅是着眼于解决现在的问题,而设计模式的“复杂”就在 于它是要构造一个“万能钥匙”,目的是提出一种对所有锁的开锁方案。在真正理解设计模式之前我一直在编写“简单”的代码.
这个“简单”不是功能的简单,而是设计的简单。简单的设计意味着缺少灵活性,代码很钢硬,只在这个项目里有用,拿到其它的项目中就是垃圾,我将其称之为“一次性代码”。

–>要使代码可被反复使用,请用’设计模式’对你的代码进行设计.

很多我所认识的程序员在接触到设计模式之后,都有一种相见恨晚的感觉,有人形容学习了设计模式之后感觉自己好像已经脱胎换骨,达到了新的境界,还有人甚至把是否了解设计模式作为程序员划分水平的标准。

我们也不能陷入模式的陷阱,为了使用模式而去套模式,那样会陷入形式主义。我们在使用模式的时候,一定要注意模式的意图(intent),而不 要 过多的去关注模式的实现细节,因为这些实现细节在特定情况下,可能会发生一些改变。不要顽固地认为设计模式一书中的类图或实现代码就代表了模式本身。
设计原则:(重要)
1.逻辑代码独立到单独的方法中,注重封装性–易读,易复用。
不要在一个方法中,写下上百行的逻辑代码。把各小逻辑代码独立出来,写于其它方法中,易读其可重复调用。
2.写类,写方法,写功能时,应考虑其移植性,复用性:防止一次性代码!
是否可以拿到其它同类事物中应该?是否可以拿到其它系统中应该?
3.熟练运用继承的思想:
找出应用中相同之处,且不容易发生变化的东西,把它们抽取到抽象类中,让子类去继承它们;
继承的思想,也方便将自己的逻辑建立于别人的成果之上。如ImageField extends JTextField;
熟练运用接口的思想:
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

 

设计模式:

1.java的23中设计模式

2.MVC模式

3.MVP 模式

[转载]AJAX(XMLHttpRequest)进行跨域请求方法详解(三) - 【孟子E章】 - 博客频道 - CSDN.NET

mikel阅读(1025)

来源: [转载]AJAX(XMLHttpRequest)进行跨域请求方法详解(三) – 【孟子E章】 – 博客频道 – CSDN.NET

注意:以下代码请在Firefox 3.5、Chrome 3.0、Safari 4之后的版本中进行测试。IE8的实现方法与其他浏览不同。

 

3,带验证信息的请求

 

身份验证是Web开发中经常遇到的问题,在跨域请求中,默认情况下是不发送验证信息的。要想发送验证信息,需要进行withCredentials 属性,下面就是一个简单请求的例子:

  1. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
  2.  “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
  3. <html xmlns=“http://www.w3.org/1999/xhtml”>
  4. <head>
  5.   <title>孟宪会之AJAX跨域请求测试</title>
  6. </head>
  7. <body>
  8.   <input type=‘button’ value=‘开始测试’ onclick=‘crossDomainRequest()’ />
  9.   <div id=“content”></div>
  10.   <mce:script type=“text/JavaScript><!–
  11.     var xhr = new XMLHttpRequest();
  12.     var url = ‘http://dotnet.aspx.cc/RequestsWithCredentials.aspx’;
  13.     function crossDomainRequest() {
  14.       document.getElementById(“content”).innerHTML = “开始进行请求……”;
  15.       if (xhr) {
  16.         xhr.open(‘GET’, url, true);
  17.         xhr.onreadystatechange = handler;
  18.         xhr.withCredentials = “true”;
  19.         xhr.send();
  20.       } else {
  21.         document.getElementById(“content”).innerHTML = “不能创建 XMLHttpRequest。”;
  22.       }
  23.     }
  24.     function handler(evtXHR) {
  25.       if (xhr.readyState == 4) {
  26.         if (xhr.status == 200) {
  27.           var response = xhr.responseText;
  28.           document.getElementById(“content”).innerHTML = “结果:” + response;
  29.         } else {
  30.           document.getElementById(“content”).innerHTML += “<br/>执行状态 status:” + xhr.status;
  31.         }
  32.       }
  33.       else {
  34.         document.getElementById(“content”).innerHTML += “<br/>执行状态 readyState:” + xhr.readyState;
  35.       }
  36.     }
  37. // —></mce:script>
  38. </body>
  39. </html>

点击“开始测试”,我们可以检测到下面的请求执行过程:

  1. GET /RequestsWithCredentials.aspx HTTP/1.1
  2. Host: dotnet.aspx.cc
  3. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-cn,zh;q=0.5
  6. Accept-Encoding: gzip,deflate
  7. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  8. Keep-Alive: 300
  9. Connection: keep-alive
  10. Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/RequestsWithCredentials.html
  11. Origin: http://www.meng_xian_hui.com:801
  12. HTTP/1.x 200 OK
  13. Date: Sun, 10 Jan 2010 14:12:26 GMT
  14. Server: Microsoft-IIS/6.0
  15. X-Powered-By: ASP.NET
  16. X-AspNet-Version: 2.0.50727
  17. Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
  18. Access-Control-Allow-Credentials: true
  19. Set-Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145path=/; HttpOnly
  20. Set-Cookie: visit=1expires=Sun, 10-Jan-2010 14:12:56 GMT; path=/
  21. Cache-Control: no-cache
  22. Pragma: no-cache
  23. Expires: -1
  24. Content-Type: text/html; charset=utf-8
  25. Content-Length: 1

从上面的响应中可以看出,Cookie 是会随请求一起发送的。如果我们多次点击测试按钮,则可以看到请求和响应的结果是这样的:

  1. GET /RequestsWithCredentials.aspx HTTP/1.1
  2. Host: dotnet.aspx.cc
  3. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-cn,zh;q=0.5
  6. Accept-Encoding: gzip,deflate
  7. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  8. Keep-Alive: 300
  9. Connection: keep-alive
  10. Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/RequestsWithCredentials.html
  11. Origin: http://www.meng_xian_hui.com:801
  12. Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145visit=2
  13. HTTP/1.x 200 OK
  14. Date: Sun, 10 Jan 2010 14:13:58 GMT
  15. Server: Microsoft-IIS/6.0
  16. X-Powered-By: ASP.NET
  17. X-AspNet-Version: 2.0.50727
  18. Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
  19. Access-Control-Allow-Credentials: true
  20. Set-Cookie: visit=3expires=Sun, 10-Jan-2010 14:14:28 GMT; path=/
  21. Cache-Control: no-cache
  22. Pragma: no-cache
  23. Expires: -1
  24. Content-Type: text/html; charset=utf-8
  25. Content-Length: 1

注意 Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145; visit=2 这一行,访问计数器已经被一起发送到服务器。

 

4,IE8 中的实现方法

IE8已经开始支持跨域访问资源了,但是,IE8提供的功能还比较简单,可以进行简单的请求,下面是一个使用的例子:

  1. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
  2.  “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
  3. <html xmlns=“http://www.w3.org/1999/xhtml”>
  4. <head>
  5.   <title>孟宪会之AJAX跨域请求测试</title>
  6. </head>
  7. <body>
  8.   <input type=‘button’ value=‘开始测试’ onclick=‘crossDomainRequest()’ />
  9.   <div id=“content”></div>
  10.   <mce:script type=“text/JavaScript><!–
  11.     var xhr = new XDomainRequest();
  12.     var url = ‘http://dotnet.aspx.cc/SimpleCrossSiteRequests.aspx’;
  13.     function crossDomainRequest() {
  14.       document.getElementById(“content”).innerHTML = “开始……”;
  15.       if (xhr) {
  16.         xhr.open(‘GET’, url);
  17.         xhr.onload = handler;
  18.         xhr.send();
  19.       } else {
  20.       document.getElementById(“content”).innerHTML = “不能创建 XDomainRequest”;
  21.       }
  22.     }
  23.     function handler(evtXHR) {
  24.       document.getElementById(“content”).innerHTML = “结果:” + xhr.responseText;
  25.     }
  26. // —></mce:script>
  27. </body>
  28. </html>

 

另外,IE8的实现方法与其他浏览器不同。更多内容请参考 XDomainRequest 对象,地址是:
http://msdn.microsoft.com/zh-cn/library/cc288060(VS.85).aspx

最后,愿意测试的朋友可以访问这个 http://dotnet.aspx.cc/SimpleCrossSiteRequests.aspx 地址进行“简单请求”的测试,本页面允许任何地址进行跨域访问。(不好意思,个人网站可能被河蟹了)

[转载]AJAX(XMLHttpRequest)进行跨域请求方法详解(二) - 【孟子E章】 - 博客频道 - CSDN.NET

mikel阅读(922)

来源: [转载]AJAX(XMLHttpRequest)进行跨域请求方法详解(二) – 【孟子E章】 – 博客频道 – CSDN.NET

注意:以下代码请在Firefox 3.5、Chrome 3.0、Safari 4之后的版本中进行测试。IE8的实现方法与其他浏览不同。

 

2,预检请求

预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。下面的2种情况需要进行预检:
a,不是上面的简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求
b,在请求中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等

 

注意:在 iis 里进行测试,必须在“应用程序扩展”里面配置 .aspx 扩展的动作允许 OPTIONS。

下面我们举一个预检的请求:

  1. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
  2.   “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
  3. <html xmlns=“http://www.w3.org/1999/xhtml”>
  4. <head>
  5. <title>孟宪会之AJAX跨域请求测试</title>
  6. </head>
  7. <body>
  8.   <input type=‘button’ value=‘开始测试’ onclick=‘crossDomainRequest()’ />
  9.   <div id=“content”></div>
  10.   <mce:script type=“text/JavaScript><!–
  11.   var xhr = new XMLHttpRequest();
  12.   var url = ‘http://dotnet.aspx.cc/PreflightedRequests.aspx’;
  13.   function crossDomainRequest() {
  14.     document.getElementById(“content”).innerHTML = “开始进行请求……”;
  15.     if (xhr) {
  16.       var xml = “<root>测试</root>”;
  17.       xhr.open(‘POST’, url, true);
  18.       xhr.setRequestHeader(“POWERED-BY-MENGXIANHUI”, “Approve”);
  19.       xhr.setRequestHeader(“Content-Type”, “application/xml”);
  20.       xhr.onreadystatechange = handler;
  21.       xhr.send(xml);
  22.     } else {
  23.     document.getElementById(“content”).innerHTML = “不能创建 XMLHttpRequest。”;
  24.     }
  25.   }
  26.   function handler(evtXHR) {
  27.     if (xhr.readyState == 4) {
  28.       if (xhr.status == 200) {
  29.         var response = xhr.responseText;
  30.         document.getElementById(“content”).innerHTML = “结果:” + response;
  31.       } else {
  32.         document.getElementById(“content”).innerHTML = “不能进行跨越访问。”;
  33.       }
  34.     }
  35.     else {
  36.       document.getElementById(“content”).innerHTML += “<br/>执行状态 readyState:” + xhr.readyState;
  37.     }
  38.   }
  39. // —></mce:script>
  40. </body>
  41. </html>

上面的例子我们发送 xml 格式的数据,并且,发送一个非标准的HTTP头 POWERED-BY-MENGXIANHUI 来说明服务器端该如何设置响应头的。

在服务器端,PreflightedRequests.aspx 的内容如下:

  1. <%@ Page Language=C# %>
  2. <mce:script runat=“server”><!–
  3.   protected void Page_Load(object sender, EventArgs e)
  4.   {
  5.     if (Request.HttpMethod.Equals(“GET”))
  6.     {
  7.       Response.Write(“这个页面是用来测试跨域 POST 请求的,直接浏览意义不大。”);
  8.     }
  9.     else if (Request.HttpMethod.Equals(“OPTIONS”))
  10.     {
  11.       //通知客户端允许预检请求。并设置缓存时间
  12.       Response.ClearContent();
  13.       Response.AddHeader(“Access-Control-Allow-Origin”, “http://www.meng_xian_hui.com:801”);
  14.       Response.AddHeader(“Access-Control-Allow-Methods”, “POST, GET, OPTIONS”);
  15.       Response.AddHeader(“Access-Control-Allow-Headers”, “POWERED-BY-MENGXIANHUI”);
  16.       Response.AddHeader(“Access-Control-Max-Age”, “30”);
  17.       //此过程无需返回数据
  18.       Response.End();
  19.     }
  20.     else if (Request.HttpMethod.Equals(“POST”))
  21.     {
  22.       if (Request.Headers[“Origin”].Equals(“http://www.meng_xian_hui.com:801”))
  23.       {
  24.         System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
  25.         doc.Load(Request.InputStream);
  26.         Response.AddHeader(“Access-Control-Allow-Origin”, “http://www.meng_xian_hui.com:801”);
  27.         Response.Write(“您提交的数据是:<br/><br/>” + Server.HtmlEncode(doc.OuterXml));
  28.       }
  29.       else
  30.       {
  31.         Response.Write(“不允许你的网站请求。”);
  32.       }
  33.     }
  34.   }
  35. // —></mce:script>

点击“开始测试”按钮,将会执行下面的一系列请求。

  1. OPTIONS /PreflightedRequests.aspx HTTP/1.1
  2. Host: dotnet.aspx.cc
  3. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-cn,zh;q=0.5
  6. Accept-Encoding: gzip,deflate
  7. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  8. Keep-Alive: 300
  9. Connection: keep-alive
  10. Origin: http://www.meng_xian_hui.com:801
  11. Access-Control-Request-Method: POST
  12. Access-Control-Request-Headers: powered-by-mengxianhui
  13. HTTP/1.x 200 OK
  14. Date: Sun, 10 Jan 2010 14:00:34 GMT
  15. Server: Microsoft-IIS/6.0
  16. X-Powered-By: ASP.NET
  17. X-AspNet-Version: 2.0.50727
  18. Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
  19. Access-Control-Allow-Methods: POST, GET, OPTIONS
  20. Access-Control-Allow-Headers: POWERED-BY-MENGXIANHUI
  21. Access-Control-Max-Age: 30
  22. Set-Cookie: ASP.NET_SessionId=5npqri55dl1k1zvij1tlw3repath=/; HttpOnly
  23. Cache-Control: private
  24. Content-Length: 0
  25. POST /PreflightedRequests.aspx HTTP/1.1
  26. Host: dotnet.aspx.cc
  27. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
  28. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  29. Accept-Language: zh-cn,zh;q=0.5
  30. Accept-Encoding: gzip,deflate
  31. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  32. Keep-Alive: 300
  33. Connection: keep-alive
  34. POWERED-BY-MENGXIANHUI: Approve
  35. Content-Type: application/xml; charset=UTF-8
  36. Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
  37. Content-Length: 19
  38. Origin: http://www.meng_xian_hui.com:801
  39. Pragma: no-cache
  40. Cache-Control: no-cache
  41. <root>测试</root>
  42. HTTP/1.x 200 OK
  43. Date: Sun, 10 Jan 2010 14:00:34 GMT
  44. Server: Microsoft-IIS/6.0
  45. X-Powered-By: ASP.NET
  46. X-AspNet-Version: 2.0.50727
  47. Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
  48. Set-Cookie: ASP.NET_SessionId=byvose45zmtbqy45d2a1jf2ipath=/; HttpOnly
  49. Cache-Control: private
  50. Content-Type: text/html; charset=utf-8
  51. Content-Length: 65

 

以上的代码反映了预检请求的执行过程:首先发送 OPTIONS 请求头,用来向服务器咨询服务器的更多信息,以便为后续的真实请求做准备。比如是否支持 POST 方法等。值得注意的是:

浏览器还发送 Access-Control-Request-Method: POST 和 Access-Control-Request-Headers: powered-by-mengxianhui 请求头。

注意:以上过程是第一次请求的时候的过程,如果在 30 秒内重复点击按钮,你可以看不到 OPTIONS 这一过程。则执行过程是这样的:

 

  1. POST /PreflightedRequests.aspx HTTP/1.1
  2. Host: dotnet.aspx.cc
  3. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-cn,zh;q=0.5
  6. Accept-Encoding: gzip,deflate
  7. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  8. Keep-Alive: 300
  9. Connection: keep-alive
  10. POWERED-BY-MENGXIANHUI: Approve
  11. Content-Type: application/xml; charset=UTF-8
  12. Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
  13. Content-Length: 19
  14. Origin: http://www.meng_xian_hui.com:801
  15. Pragma: no-cache
  16. Cache-Control: no-cache
  17. <root>测试</root>
  18. HTTP/1.x 200 OK
  19. Date: Sun, 10 Jan 2010 14:06:32 GMT
  20. Server: Microsoft-IIS/6.0
  21. X-Powered-By: ASP.NET
  22. X-AspNet-Version: 2.0.50727
  23. Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
  24. Set-Cookie: ASP.NET_SessionId=qs1c4urxywdbdx55u04pvualpath=/; HttpOnly
  25. Cache-Control: private
  26. Content-Type: text/html; charset=utf-8
  27. Content-Length: 65

 

为什么会这样?细心的童鞋可能注意到了,在服务器端有一行代码 Response.AddHeader(“Access-Control-Max-Age”, “30”);  它是用来设置预检的有效时间的,单位是秒。这一点要特别注意。

[转载]AJAX(XMLHttpRequest)进行跨域请求方法详解(一) - 【孟子E章】 - 博客频道 - CSDN.NET

mikel阅读(664)

来源: [转载]AJAX(XMLHttpRequest)进行跨域请求方法详解(一) – 【孟子E章】 – 博客频道 – CSDN.NET

注意:以下代码请在Firefox 3.5、Chrome 3.0、Safari 4之后的版本中进行测试。IE8的实现方法与其他浏览不同。

跨域请求,顾名思义,就是一个站点中的资源去访问另外一个不同域名站点上的资源。这种情况很常见,比如说通过 style 标签加载外部样式表文件、通过 img 标签加载外部图片、通过 script 标签加载外部脚本文件、通过 Webfont 加载字体文件等等。默认情况下,脚本访问文档属性等数据采用的是同源策略(Same origin policy)。

那么,什么是同源策略呢?如果两个页面的协议、域名和端口是完全相同的,那么它们就是同源的。同源策略是为了防止从一个地址加载的文档或脚本访问或者设置 从另外一个地址加载的文档的属性。如果两个页面的主域名相同,则还可以通过设置 document.domain 属性将它们认为是同源的。

随着 Web2.0 和 SNS 的兴起,Web 应用对跨域访问的需求也越来越多,但是,在脚本中进行跨域请求是受安全性限制的,Web 开发人员迫切需要提供一种更安全、方便的跨域请求方式来融合(Mashup)自己的 Web 应用。这样做的一个好处就是可以将请求分摊到不同的服务器,减轻单个服务器压力以提高响应速度;另外一个好处是可以将不同的业务逻辑分布到不同的服务器上 以降低负载。

值得庆幸的是,跨域请求的标准已经出台,主流浏览器也已经实现了这一标准。W3C 工作组中的 Web Applications Working Group(Web 应用工作组)发布了一个 Cross-Origin Resource Sharing(跨域资源共享,该规范地址:http://www.w3.org/TR/access-control/和http: //dev.w3.org/2006/waf/access-control/) 推荐规范来解决跨域请求的问题。该规范提供了一种更安全的跨域数据交换方法。具体规范的介绍可以访问上面提供的网站地址。值得注意的是:该规范只能应用在 类似 XMLHttprequest 这样的 API 容器内。IE8、Firefox 3.5 及其以后的版本、Chrome浏览器、Safari 4 等已经实现了 Cross-Origin Resource Sharing 规范,已经可以进行跨域请求了。

Cross-Origin Resource Sharing 的工作方式是通过添加 HTTP 头的方法来判断哪些资源允许 Web 浏览器访问该域名下的信息。然而,对于那些 HTTP 请求导致用户数据产生副作用的请求方法(特别是对于除了GET、某些 MIME 类型的 POST 之外的 HTTP方法),该规范要求浏览器对请求进行“预先验”,通过发送 HTTP 的 OPTIONS 请求头询问服务器有哪些支持的方法,在征得服务器的同意后,再使用实际的 HTTP 请求方法发送实际的请求。服务器也可以通知客户端是否需要将验证信息(如 Cookie 和 HTTP Authentication 数据)随同请求一起发送。

下面我们就采用实际的例子说明 Cross-Origin Resource Sharing 是如何工作的。

 

1,简单请求

 

什么样的请求算是简单请求呢?简单请求必须满足下面2点:
a,只使用 GET、POST 进行的请求,这里的POST只包括发送给服务器的数据类型(Content-Type)必须是 application/x-www-form-urlencoded、multipart/form-data 或者 text/plain中一个。
b,HTTP 请求没有设置自定义的请求头,如我们常用的 X-JSON。

 

先使用下面的代码进行测试:

  1. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
  2.  “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
  3. <html xmlns=“http://www.w3.org/1999/xhtml”>
  4. <head>
  5.   <title>孟宪会之AJAX跨域请求测试</title>
  6. </head>
  7. <body>
  8.   <input type=‘button’ value=‘开始测试’ onclick=‘crossDomainRequest()’ />
  9.   <div id=“content”></div>
  10.   <mce:script type=“text/JavaScript><!–
  11.     var xhr = new XMLHttpRequest();
  12.     var url = ‘http://dotnet.aspx.cc/SimpleCrossSiteRequests.aspx’;
  13.     function crossDomainRequest() {
  14.       document.getElementById(“content”).innerHTML = “开始……”;
  15.       if (xhr) {
  16.         xhr.open(‘GET’, url, true);
  17.         xhr.onreadystatechange = handler;
  18.         xhr.send();
  19.       } else {
  20.         document.getElementById(“content”).innerHTML = “不能创建 XMLHttpRequest”;
  21.       }
  22.     }
  23.     function handler(evtXHR) {
  24.       if (xhr.readyState == 4) {
  25.         if (xhr.status == 200) {
  26.           var response = xhr.responseText;
  27.           document.getElementById(“content”).innerHTML = “结果:” + response;
  28.         } else {
  29.           document.getElementById(“content”).innerHTML = “不允许跨域请求。”;
  30.         }
  31.       }
  32.       else {
  33.         document.getElementById(“content”).innerHTML += “<br/>执行状态 readyState:” + xhr.readyState;
  34.       }
  35.     }
  36. // —></mce:script>
  37. </body>
  38. </html>

 

然后,在服务器创建 CrossDomainRequest.aspx 的内容如下:

  1. <%@ Page Language=C# %>
  2. <mce:script runat=“server”><!–
  3.   protected void Page_Load(object sender, EventArgs e)
  4.   {
  5.     Response.AddHeader(“Access-Control-Allow-Origin”, “http://www.meng_xian_hui.com:801”);
  6.     Response.Write(“孟宪会向各位朋友发来贺电:你的第一个跨域测试成功啦!!!”);
  7.   }
  8. // —></mce:script>

 

点击 “开始测试” 按钮,发送的请求和返回的响应信息如下:

 

  1. GET /SimpleCrossSiteRequests.aspx HTTP/1.1
  2. Host: dotnet.aspx.cc
  3. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-cn,zh;q=0.5
  6. Accept-Encoding: gzip,deflate
  7. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  8. Keep-Alive: 300
  9. Connection: keep-alive
  10. Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/SimpleCrossSiteRequests.html
  11. Origin: http://www.meng_xian_hui.com:801
  12. HTTP/1.x 200 OK
  13. Date: Sun, 10 Jan 2010 13:52:00 GMT
  14. Server: Microsoft-IIS/6.0
  15. X-Powered-By: ASP.NET
  16. X-AspNet-Version: 2.0.50727
  17. Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
  18. Set-Cookie: ASP.NET_SessionId=wk5v5nrs5wbfi4rmpjy2jujbpath=/; HttpOnly
  19. Cache-Control: private
  20. Content-Type: text/html; charset=utf-8
  21. Content-Length: 84

需要特别注意的是:在请求信息中,浏览器使用 Origin 这个 HTTP 头来标识该请求来自于 http://www.meng_xian_hui.com:801;在返回的响应信息中,使用 Access-Control-Allow-Origin 头来控制哪些域名的脚本可以访问该资源。如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源。如果有多个,则只需要使用逗号分隔开即可。

注意:在服务器端,Access-Control-Allow-Origin 响应头 http://www.meng_xian_hui.com:801 中的端口信息不能省略。

有人可能会想:自己发送请求头会如何呢?比如 xhr.setRequestHeader(“Origin”,”http://www.meng_xian_hui.com:801″); 实践证明,自己设置 Origin 头是不行的。

是不是现在就可以采用 XMLHttpRequest 来请求任意一个网站的数据呢?还是不行的。允许哪些域名可以访问,还需要服务器来设置 Access-Control-Allow-Origin 头来进行授权,具体的代码是:

Response.AddHeader(“Access-Control-Allow-Origin”, “http://www.meng_xian_hui.com:801”);

这行代码就告诉浏览器,只有来自 http://www.meng_xian_hui.com:801 源下的脚本才可以进行访问。

好了,上面我们就完成了一个简单的跨域请求,怎么样?感觉还是不错的吧。下面我们进行一个“预检”请求。

[转载]介绍四款windows下的神器 - Xiangism - 博客园

mikel阅读(1055)

来源: [转载]介绍四款windows下的神器 – Xiangism – 博客园

四款神器:Q-dir, Cmder, Everythinglaunchy

Q-dir

Q-dir: windows自带资源管理器explorer的加强版。(windows自带的资料管理器explorer,不能合并窗口浏览,程序员经常会有打开多个窗口的需求,在多个explorer窗口间切换是件非常不舒服的事情)

Q-dir支持最多4个窗口同时多开,tab页无限多开,不同文件类型的不同颜色区别(且支持自定义颜色),可以还原上次关闭时已打开的窗口等等。

并且文件/文件夹图标、右键菜单与explorer完全一样。

缺点:

  1. 不能禁用掉拖放功能。(本人非常不喜欢拖放功能–容易将文件误拖)这个软件也不开源,不能自己来修改。
  2. 文件列表中的字体稍微有点小,并且不能自定义字体大小。

在codeproject上找到个 C# File Browser,但其实现的不够完美,并且也不能显示svn,git项目中的同步图标。有个CubicExplorer是用dephi实现的开源软件,图 标和右键菜单很完美,但自己不熟悉dephi,不能快速地实现一个与Q-dir类似的软件。就将就地用Q-dir吧

Cmder

Cmder: 系统自带控制台的加强版。

系统自带控制台的缺点:

  1. 自定义字体支持得不够好。捣腾注册表,将公司电脑上将字体改成了DejaVu Sans Mono,但自己家中的电脑死命都是默认的字体。
  2. win7下控制台不支持ctrl-v,只能右键然后p。复制的话就更2了,要先点左上角,然后点编辑-标记,然后选择,最后回车。 虽说win10下的控制台有ctrl-v了,但用惯了win7一时也不会因为控制台的ctrl-v而去win10下工作。

先看一下Cmder的界面:

  1. 完美支持自定义字体。
  2. ctrl-v粘贴无压力;直接鼠标选词后就完成了复制。
  3. 支持tab页多开。
  4.  …

配置

  1. 将cmder.exe所在路径添加到系统路径PATH
  2. 默认情况下中文显示有点问题,得配置。在cmder_mini/config/aliases文件最后添加
    l=ls --show-control-chars 
    la=ls -aF --show-control-chars 
    ll=ls -alF --show-control-chars 
    ls=ls --show-control-chars -F

    然后在设置Main右侧,去掉”Monospace”的勾选即可

  3. 默认命令提示符是”λ”
    cmder_mini/config/prompt.lua 第二行最后”λ”修改为”$”即可
  4. 将Cmder添加到文件夹的右键菜单
    (explorer和命令行窗口相互打开,请参看本人的另一篇博文 http://www.cnblogs.com/xiangism/p/4467603.html)
    执行 cmder /register user 即可
    如果想使用快捷键Q,可以在注册表HKEY_CLASSES_ROOT\Directory\Background\shell 给Cmder前面添加Q,在其子项默认的数据前添加Q即可

Everything

相当于linux下的locate工具。启动这个软件时,首先会全盘检索所有文件,然后搜索文件时就相当快。并且支持各种搜索模式,当然包含正则搜索了。比如用\.pdf$ 正则搜索就可以找出电脑中所有的pdf文件了 !!!

缺点: 对于新插入的u盘或移动硬盘其也会检索所有文件,这时就不能安全退出设备,只能等其检索完成,或者先关闭everything.

launchy

可快速启动其它程序。

一般情况下电脑中所装应该至少会几十个,如果使用时在开始-所有程序中去找就太慢了。

用launchy可以实现快速启动程序。

本人建立了一个d:\desk文件夹,将所有程序入口的快捷方式用最短的拼音重命名后放入其中,然后添加launchy的搜索目录。这样如果想启动word,只需要按Alt+Enter启动launchy,再输入word,再回车,即可启动word

 

 

最后: 四款神器,总有一款适合你的口味