今天在查看windows日志中的应用程序日志时,发现如下错误:

无法找到来自源 Zend Loader 的事件 ID 5 的描述。本地计算机上未安装引发此事件的组件,或者安装已损坏。可以安装或修复本地计算机上的组件。

如果该事件产生于另一台计算机,则必须在该事件中保存显示信息。

以下是包含在事件中的信息: 

C:WINDOWSTEMPZendLoader.MemoryBase@SYSTEM@3391924446 拒绝访问。

系统:windows 8.1
web环境:nginx/1.5.3 PHP/5.3.27

依旧是先Google了一下,在这篇文章里找到了解决方式

看了不是很理解,找了其中的几个关键词:php.ini,upload_tmp_dir,C:WINDOWSTemp,Network Service,IIS_WPG,ZendOptimizer.MemoryBase@SYSTEM和ZendOptimizer.MemoryBase@NETWORK SERVICE。

大体的意思是:在php.ini中upload_tmp_dir的值为C:WINDOWSTemp的时候,在确保ZendOptimizer.MemoryBase@SYSTEM和ZendOptimizer.MemoryBase@NETWORK SERVICE两个文件存在的时候(没有则新建一个命名相同的空文件),给Temp文件夹添加Network Service和IIS_WPG的写入权限,就能解决问题。

然后我根据这个思路,开始着手根据我自己的环境和配置,尝试着解决问题。

首先,我的php.ini中,关于upload_tmp_dir这块如下:

;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On

; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
;upload_tmp_dir =

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 32M

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

我的upload_tmp_dir 是被注释掉的,但是file_uploads 是开启的,所以upload_tmp_dir 用的是默认的值。然后在这篇文章中找到如下一句话:

The reason for this is, the uploaded file will inherit the permissions of the directory specified in the directive upload_tmp_dir of php.ini.  If this directive isn't set, the default of C:WindowsTemp is used.

所以我的upload_tmp_dir 在默认值的情况下用的是 C:WindowsTemp

在我的Temp文件夹下是有文件ZendLoader.MemoryBase@SYSTEM@3391924446的,这一点和文章里面说的不太一样,可是我的错误信息里面明确是指定这个文件的,所以暂时不需要添加那两个空文件。

然后就是给Temp文件夹添加权限了,首先得知道Network Service和IIS_WPG分别代表什么?

看MSDN上面的,可以知道Network Service是一个被服务控制管理器(service control manager)使用的本地账号,用来在网络中代表这台计算机。

这篇文章里面找到的针对IIS_WPG的定义是:

There was also a group called IIS_WPG, which was used as a container for all the application pool identities. During IIS setup, all the appropriate resources on the system were granted the correct user rights for the IIS_WPG group so that an administrator only needed to add their identity to that group when they created a new application pool account.

大致的意思是给所有IIS应用管理权限的一个组。

可问题是,我用的不是IIS,所以得找到和Nginx相关的账号.可是看了下,貌似nginx和IIS不一样,它是一个服务,是运行在本地系统账户下的一个服务。所以我不知道该怎么办了。先给Temp账户添加了Network Service的写入权限。然后清空日志,看看明天重启的时候报什么错吧

============== 后续更新 =====================

2013年10月24日

今天开机一段时间之后,查看应用程序日志,没有发现此错误

2013年10月25日

今天开机之后,查看应用程序日志,问题再次出现,分为两种问题状态:

C:WINDOWSTEMPZendLoader.MemoryBase@SYSTEM@3391924446
拒绝访问。

Unable to write base address
拒绝访问。

最近在做兼容多浏览器能跨域访问的本地存储实施方案。一开始打算是用localStorage加userData的方式实现,支持localStorage的使用localStorage,不支持的(IE6,7)使用userData;本域下的直接调用,需要跨域的则加载对应域名下的crossdomain.html作为iframe,然后调用iframe里面的contentWindow来实现。

想法是很好的,也实现了很多功能,但是在实现之后的的评审和准备应用阶段,却发现了很多开发的时候没有注意到的问题。

Document Limit/Doamin Limit

可以看看下面的表格,在每个域名下的存储限制是1M,这个很多很令人满意,但是还有个Document Limit在当初使用的时候却忽略了。userData的实现方式就是加载一个放在用户文件夹下的XML文件,在里面进行I/O操作。这每一个XML文件就是一个Document。而操作的时候,必须明确指定加载哪个XML文件。这就和localStorage的实现方式上有了很大的差别,不利于统一。而且单个Document的大小是128KB,这个很难保证后期能否足够使用。

Security Zone Document Limit (KB) Domain Limit (KB)
Local Machine 128 1024
Intranet 512 10240
Trusted Sites 128 1024
Internet 128 1024
Restricted 64 640

same directory and same protocol to access

上面那个文档的大小限制和明确指定加载的XML文件,还不算很坑的。因为短时间内128KB肯定是足够使用的,也可以在实施方案里面统一各域名下加载同一个名称的XML就好了。也就是看起来像每个域名下只有128kb的存储空间。

可是下面这个限制就很坑了。

对于userData,数据之间的划分,不单单是域名,协议和端口号这三个。它还更加严格的以文档路径进行划分,对的,不用怀疑:http://www.demo-domain.com/test/index.html是没法访问到http://www.demo-domain.com/test2/index.html里面的userData数据的。

当然,这个也能绕开,就是在使用userData的情况下,所有的I/O操作都是走的iframe,哪怕是同域名下。然后给所有域名的根域放置一个crossdomain.html。但是这样的实施方法确实有点复杂

can’t be set/get in <head>

接着还有问题,这个问题是个使用上的限制。在公司的应用环境里,有些情况,需要在加载head的时候,就能读到本地的数据,然后做一个是否跳转的判断。而userData绑定的标签是不包括head里面能放置的那些。所以很不幸userData无法实现

而且通常的使用方式是认为的createElement,然后在这个element上面进行文档的绑定。而在IE6下,向文档插入dom是必须要在document.ready之后进行的,不然会容易出现问题

can’t clear and Traversal(like function key in localStorage)

最后一个问题,在实施方案里面,公开的接口都是仿造localStorage的接口。其中有两个接口clear(清空所有内容)和key(遍历本地数据)。这两个接口使用的场景不多,但是肯定是会有使用到的时候,可惜userData的官方文档里面并没有看到有这相关的接口提供。

所以,因为上面这么多的问题,只好忍痛放弃已经开发完的localStorage和userData的组合,改为使用localStorage和FlashCookie的组合。

方法一

今天在做一个兼容且可跨越的localStorage的实施方案,打算使用github进行项目的代码管理和版本控制。工作环境是Windows,用的git工具是msysgit。

git clone,git commit,git push。这一套下来工作的很流畅,很正常,可是有一点比较麻烦,就是每次push的时候,总是要输入一次在github上面的帐号和密码。就想着能不能在本地存储这个帐号和密码,每次push的时候就自动提交这个去验证。

Google了一下,在一个github的帮助教程的快照上面看到了详细的关于如何在push到远程仓库时,不同系统下面如何去保存验证信息。其中提到了一个软件:git-credential-winstore,这个是专门在Windows下面用来管理git的验证信息的。然后在github的官方帮助文档:上面,找到了软件的官方地址(其实上面那个快照对应的就是下面那个地址的,可能是github更新了,所以内容有些不同,过段时间,Google那边更新快照之后应该就相同了)

可是在安装git-credential-winstore.exe的时候出了问题,会提示无法识别git,软件里面给的解决方式有两种:

  1. 在系统的环境变量PATH里面加上git的安装目录
  2. 通过cmd进行安装 安装使用如下命令行

明确的指定git所在位置

git-credential-winstore.exe -i C:Program Files(x86)Gitcmdgit.exe

可惜这两种方式我试过了都失败了。最后在这个文章上才找到解决方式:git-credential-winstore.exe必须放到git的安装目录里面,在bin/文件夹下。

安装这篇文章里面指示的放置文件之后,双击安装,还是报之前的错误。不过幸运的是,通过cmd的方式进行安装成功了。

原因应该是我的环境变量设定有问题吧,不清楚C:Program Files(x86)Gitcmd和C:Program Files(x86)Gitbin应该使用哪一个,这两个目录下面都是有git.exe的。

安装完成之后,就是如何在git里面配置和使用了。

在最开始看的那篇文章里面,说的配置是这样的

git config --global credential.helper cache

作用是启用验证信息缓存功能

可是我按上面的配置之后,在push的时候,却提示:‘credential-cache’ is not a git command

很明显,配置有问题的,可是git实在是新手,只好再次Google之,然后在Stack Overflow上面看到了这个帖子
说在Windows下面,那个配置中的cache应该改成winstore,正确的命令应该是这样的:

git config --global credential.helper winstore

按照这个命令重新执行了下,果然可以,在第一次push的时候,会有个弹窗,让你输入在github上面的帐号和密码,然后再次push的时候,就不必再输入帐号和密码了。

估计那篇文章里面使用cache,是指的在Linux下的吧,而在Windows下面使用git-credential-winstore来管理验证信息,所以credential.helper就应该是winstore

方法二

昨天(20150310),有个同事介绍了一个我认为使用上虽然啰嗦一点但是更便捷的方法,虽然在安全性上,有点无法保障。在这里跟大家介绍一下,也可以看这里原文地址

直接进入正题,步骤如下:
1. Windows中添加一个用户变量(开始-系统-高级系统设置-环境变量),名称为:HOME,值为%USERPROFILE%
设置用户变量
2. 在“开始-运行”中输入%Home%后确定,在打开的文件夹下新建一个名为_netrc的文件。
运行%Home%
新建_netrc文件
3. 用记事本打开_netrc文件,输入Git服务器名、用户名、密码,并保存,例如:

machine git.yourserver.org ---- git服务器名称
login yourlogin@email.com ---- git用户名
password yourpassword123 ---- git账号密码

关于localStorage,在简单不过的接口,getItem,setItem,removeItem,clear,key.这些大家都很了解,可是也有一些细节,如果不注意的话也是可能导致一些问题的。

支持范围

localStorage的支持范围比想象的要广很多,市面上手机端和PC端的浏览器,除开IE,几乎都支持(指从很低版本就开始支持),而一向拖后腿的IE,在IE8中也是支持localStorage的。所以,放心使用吧!以下是各浏览器下的支持情况:

IE FIREFOX SAFARI CHROME OPERA IPHONE ANDROID
8.0+ 3.5+ 4.0+ 4.0+ 10.5+ 2.0+ 2.0+

来源限制

localStorage对来源的认定是根据以下规则:协议+域名+端口

协议

http:// 里面的数据和 https:// 里面的是分离的

所以http://www.demo-domain.com/下面localStorage里面的数据,在https://www.demo-domain.com/里面是没法访问到的

域名

域名是必须完全一致的,下属的二级,三级域名都是没法访问根域名下面的数据的。

所以http://t.www.demo-domain.com/是没法访问到http://www.demo-domain.com/页面里面localStorage的数据

端口

这个比较少见,大部分对外公开的网站,都是默认的80端口。同域名和协议,但是端口不同的页面,也是没法共享localStorage的数据的

比如:http://www.demo-domain.com:8080/ 页面是没法访问 http://www.demo-domain.com/ 页面中的localStorage数据

浏览器的“模式”

现在很多浏览器都提供了“匿名访问”,“安全模式”,“隐身窗口”等等功能。在这种情况下,浏览器都是会重新建立一个新的localStorage,所以这些模式下的页面是没法访问在正常模式下的页面中的数据。

借鉴的文章地址:http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html

起因

在知乎上面看一个关于回调函数的帖子时,有人为了表明观点,就给了个链接说是代码示例.好奇心强大,就点了过去.然后就发现了这么个前端代码在线调试和分享的利器–jsFiddle

jsFiddle的主要用途

个人觉得jsFiddle有下面几个使用场景:

  • 写代码的时候,(可能是html,可能是css,也可能是js,有些东西没把握或者不清楚,但是现有的工程复杂度太高,不好直接拿来测试.重新建立个html文件然后写doctype,html,head…这个过程又太麻烦。可能环境搭建好,想法也没了。这个时候比较直接的方式就是打开浏览器,地址栏输入jsFiddle.net。然后立马开始需要进行的测试工程。
  • 写技术博客或者回复评论(前提是这个评论支持加入iframe)的时候,需要展示一些代码。需要面临两个问题:一个是好的代码高亮,二是代码的实际运行结果。有些网站有这个功能(也许wordpress也有这样的插件,只是我还没接触到),一个展示代码的文本框,下面一个按钮“运行代码”,点击就会跳转到另一个页面看代码的实际运行效果。但是在jsFiddle的代码分享就有个比较好的地方,通过tab选项卡的方式可以方便的切换显示html,css,js的代码和实际的运行效果。当然,这个对于小片段的代码最有优势,如果是太复杂的效果则肯能不是很适合了
  • jsFiddle还有一个git思想的fork功能,这样就很方便你在查看别人代码的同时,能进行简单的修改调试,这样能进一步的理解

一些使用方面的技巧

jsFiddle网站本身也提供了很详细的使用文档,不过只有英文版的,英文还不错的同学可以看这里

界面介绍

界面有两种状态,一种是没保存前也就是通过地址直接访问的时候,一种是在前一种状态中点击顶部菜单中的”save”之后

两种状态的主要区别也是在顶部菜单栏。

两种状态下的菜单栏

保存之前的菜单

保存之前的菜单

保存之后的菜单

保存之后的菜单

第一种状态中特殊的按钮是”save”,可以把当前编辑的项目保持到jsFiddle的服务器上面,这样方便再次查看和分享

第二种状态中特殊的按钮有”update”,”fork”,”base”/”set as base”和”share”

像”update”和”fork”都是类似github的方式

“update”就是将当前状态保存为一个版本,方便调试(只有初始版本和update版本,这两个版本).

“fork”就是把当前的项目复制到一个新建项目中

“base”按钮出现在没有进行过”update”或者最初版本的项目中,表明这是最初始的版本,点击没效果,只是标识作用

“set as base”相反,出现在非初始版本的项目中。可点击,作用是把当前版本变成最初版本,原先的初始版本会被删除

“share”点击之后会展开一个面板,提供三种形式的分享方式

  • 一个是当前项目的地址,进入后看到的和作者当前看到的内容一样
  • 一个是全屏的tab选项卡展示代码和结果。不过默认提供的只是结果的展示。需要了解url的规则才好自定义
  • 第三种其实就是用iframe引用的第二个的地址。
    还有4个公用的菜单按钮

  • “run” 是执行代码,点击之后就能在右下角的result区域看到代码执行的结果
  • “debug on mobile”(就是那个类似手机上表示信号的图标), 是用来进行手机端调试使用的
  • “TidyUp” 是整洁代码
  • “JSHint” 是js的错误检查

代码编辑区

代码编辑区

代码编辑区

分为四个区块,分别是html,css,js的输入区域,和代码运行的结果展示区域result

可以拖动区块直接的框去控制各个区块的大小

功能区

功能区

功能区

功能区在代码编辑区的左侧

Framework&Extensions 是程序需要用到的类库,有jQuery,YUI,ExtJs,Dojo等等,但是很可惜,国内的KISSY貌似没有的

Fiddle Options

  • Name,Description 是对当前代码的一个命名和描述,方便以后在个人平台上面查看
  • Normalized CSS 这个是选择是否加载一个reset css的文件,去除一些浏览器默认添加的样式
  • Body tag 可以自定义body标签,这个是考虑到某些类库需要给body标签添加类或者别的属性
  • DTD 定义html文档的类型申明,默认是html5的
  • Framework attribute 用来定义加载类库的script标签上面的一些属性

编写代码

草稿

对于登录的用户,对于当前正在编辑的jsfiddle里面的代码,只要你点击过run,那么就可以通过访问jsfiddle.net/draft/ 来查看看看运行过的代码的执行页面,展示的内容和result里面一样。

这样做的一个很大的好处是:能够方便的比较在不同浏览器下,代码的执行结果的不同,当然,前提是在不同的浏览器下,得先登录了。

分享代码

jsFiddle里面,除了能够很方便开发者去写一些demo之外,很大的一个好处就是高度可自定义的设定分享的展示方式。在点击save按钮之后,得到的页面地址,只要把这个地址发送给你想分享的对象,那么对方就能通过这个地址看到和你save之后一模一样的界面。同时,点击share按钮,在弹出菜单里面Share link里面的值也就是这个值。Embed on your page,这个里面是一个html代码,可以放在你的文章里面,方便在文章中添加代码。就比如我这个

还有一种http://jsfiddle.net/shuizhongyueming/L49jh/embedded/result/。这个地址是可以配置的,在地址的embedded后面,有四种无序参数:html,css,js,result 以逗号分隔,只要在地址里面按需加入需要的即可。同样,那个IFrame的src值也是可以这样设定的
比如,如果我想向人分享我的demo里面的js和result。那么我可以http://jsfiddle.net/shuizhongyueming/L49jh/embedded/js,result/。那么demo的展示页面里面,就会有两个tab页,顺序和地址里面的顺序一致。

结语

以上差不多是我所知的关于jsfiddle的全部东西了。欢迎指正和补充