Javascript的KeyCode

在前端开发中,经常使用onkeypress,onkeydown等event来做快捷键。
我之前就是打算使用“;”来做快捷键功能。
使用了如下代码

document.onkeydown = function(e) {
    e = e || window.event;
    var kcode = e.which || e.keyCode;
	if(String.fromCharCode(kcode) == ";") {
              // TODO Place your code here.
	}
};

结果。。。只有在Firefox好用,Chrome和IE都阵亡了。
我并没有做任何的浏览器判断,怎么会自动按浏览器区分功能呢?

原来,对于event的keycode,大部分的按键的keycode值在所有浏览器中都是一致的。
但是,有一小撮按键。。。。很不幸就有我选中的的“;”,在firefox和Chrome中是不一致的。
具体列表参照http://www.javascripter.net/faq/keycodes.htm

Apache与Nginx

之前的服务器都是随大流使用的Apache,后来在新的备份服务器上美滋滋的想着尝试一下Nginx。
结果悲剧了。常用几个开源应用的.htaccess都是默认自带Apache语法的。尝试了一下网上的翻译器,并没有什么卵用。
小众者必然会死。。

// update

经过艰苦卓绝的训练。
技能【反向代理某搜索引擎】 Get。
技能【用Nginx进行负载平衡】 Get。

Salesforce如何取得Guest User的Debug Log

// Update4 2018/04/10

Salesforce这次不仅吃书。。。连设定都吃回去了。。。
这篇文章不用看了,以后再也不用设Cookie了。一切又回到了最初的样子。
官方文档

从Winter’17开始,Guest User的Debug Log不再能通过正常渠道直接获取了。这给我们做Wechat集成的小伙伴们造成了很大的困扰。
虽然说官方文档中,介绍了在Chrome下使用插件添加Cookie的方法来激活Guest User的Debug log,但微信里是没法修改Cookie的。
不过官方提到了可以通过各种代码添加Cookie的Sample Code,尤其是Javascript,可以放到被访问的页面上。
代码只有简简单单的一句

document.cookie ="debug_logs=debug_logs;domain=.force.com";

在修改了Page之后,兴冲冲的打开了微信进行测试,发现并没有卵用。
然后切回浏览器,通过浏览器访问发现,这段Js代码加入的Cookie值与我之前用插件添加进去的值并完全不一致。
不一致的属性是“Path”,由于我的Salesforce Site是设定了Path的,所以Js代码生成的Cookie的Path也跟着变成了我设定的Path。而我用插件加入的Cookie的Path属性默认为“/”。
好,那么我们修改一下这句Js

document.cookie ="debug_logs=debug_logs;domain=.force.com;path=/";

修改完之后再试,问题解决,Debug Log乖乖出来了。
打完收工。

// Update 1

微信内置浏览器是可以使用Cookie的,不过要慎重,因为微信的内置浏览器对于Cookie的处理策略与桌面浏览器不是很一致,并且每个版本都有变动。所以不应该过度依赖于微信内置浏览器的Cookie。

// Update 2

微信的内置浏览器为X5内核,所以行为和渲染等都与Webkit内核有出入。慎重!!
另,Spring’17 开始进入倒计时的时候,发现前文提到的官方文档不见了!!但是此方法仍然有效!!到底发生了什么!!

// Update 3
对于Salesforce官方不断吃书的行为表示不满与谴责(Knowledge文章被取消了)。
然并卵,已经不是第一次吃书了,所以想参考官方文档的同学看这里

关于Lorem Ipsum

对于前端开发人员来讲,涉及到内容填充或者排版的时候,最常用的就是Lorem Ipsum文本。

标准文本内容

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

// Update 1

在Word里如果输入=Rand()会随机的生成一段文本给你当填充物,或者输入=lorem(),则是填充Lorem Ipsum。当然这两个函数都贴心的设置了可选参数,可以选择长度与段落数量等。

Salesforce不登录调用Webservice的方法

Salesforce中提供了WebService的调用方式,在系统内部使用的时候,比如通过VF上的JS,或者通过标准页面上的按钮进行调用,可以方便的实现很多功能。
同时,Salesforce中的WebService可以也以rest方式提供给第三方系统进行可控的数据交互。
但是,鉴于Salesforce的License价格虚高,并且有些第三方,例如微信后台是无法进行身份认证的时候,通过public site开放WebSerivce用rest方式调用就非常有必要了。

首先,要在Webservice的首行添加@RestResource(urlMapping=’/{your name}/*’)
之后定义好@HttpGet方法或者@HttpPost方法。

将WebService类及相关类加到Site的可访问Apex Class列表里。
准备完毕后确认site有没有设定Path。
如果是sandbox的话
https://{prefix}.{sandbox instance Name}.force.com/{path}/services/apexrest/{Name Space}/{webservice urlMapping Name}/{your paramater}
如果是Production的话,
https://{prefix}.secure.force.com/{path}/services/apexrest/{Name Space}/{webservice urlMapping Name}/{your paramater}

尤其是Name Space,曾经难倒无数英雄汉。

Salesforce删除数据时出现Insufficient privileges的可能原因

遇到一个诡异的情况,用户通过界面删除一条自定义Object的数据的时候出现了Insufficient privileges。
按理说,如果用户的Profile没有此Object的删除权限的话,应该连删除按钮都看不到才对。

事情有蹊跷。首先检查了Profile,增删改查都有,但是没有Motify All和View All。
那么排除了Profile的嫌疑。
接下来查看Role。发现此用户的Role在role hierarchy中已经是比较高的位置了。
然后检查Sharing Rule。发现此Object的基本Sharing设定已经改成了Private,并且启用了role hierarchy。
那么问题就应该出在这里了。
去查看用户无法删除的那条数据,果然Owner不是用户本人,且Owner的Role与此用户同级。

在Salesforce中,如果Object的全局Sharing Rule为Private,那么除非用户的Profile是System Admin或者拥有Motify All权限,否则当用户想删除的数据的Owner为别人且Role为同级或者更高级的话,就会出现权限不足的问题。

告知用户,想删除此数据的话,请先把Owner改成自己,然后再删除。问题解决。

参考来自官网的信息

Task中的字段TaskSubType在ApexClass中不可见问题

在Task上有一个标准字段叫做TaskSubType,是一个Picklist。在属性页面无法看到与选择任何属性。也无法更改Picklist里的值,虽然里面有内置三个值。

某一天,我试图在Task的trigger里判断字段TaskSubType的值,在保存代码时报错,错误内容为“Error: Compile Error: Invalid field TaskSubtype for SObject Task”。

我用查询工具查询该字段,正常。
我用匿名块访问该字段,正常。

奇了个怪了。

使用查询工具查看该字段,有create-able,filter-able,nillable,restricted picklist,sort-able,没有update-able。不过应该不影响这里。也查看了FLS,也没有问题。

好,耐心查看Task的文档,发现此字段原名ActivitySubType,是在Winter’16加入Salesforce的。再回头一看ApexClass,原来用的是API 30。

果断改成API 36。保存正常。

这个就类似于Java的JDK,在JDK1.8加入的新特性,在JDK1.4是肯定无法使用的。
较早前创建的Apex Class或者Visualforce Page一定要注意API版本问题。

Salesforce的Trust终于改版了

trust site是由Salesforce提供,用来监控所有服务与实例状态的网站。

经典应用场景是,发现实例变得很慢,然后打开trust,哦。。。发生了性能降低。

新版trust也提供了新版API,可以获得相关实例的JSON串,自己定时获取,自己解析,可以实现自动提醒,自动警报。

API地址 https://api.status.salesforce.com/v1/instances/{你的实例名}/status

所有接口的说明 https://api.status.salesforce.com/v1/docs/

phpfreechat中一个啼笑皆非的Bug

因为觉得所有在线聊天工具要经过人家的服务器不够把握,所以在自己的服务器上架设了phpfreechat。
这款在线聊天室,有着不在服务器储存任何聊天记录的优点。

然后有一天,我试图在上面发送一个数字 0
没有任何反应。
习惯性的按了下F12,发现phpfreechat提供了控制台输出。

readyState: 4, responseText: "{ "error": "Wrong message format (must be a JSON string)" }", status: 400, statusText: "error"}

哦?必须是个Json?
又去下了一份源代码,查找报错内容 “Wrong message format (must be a JSON string)”。
顺利定位到唯一一本代码,channels.php中的如下代码片段。

  // check that request content contains a message
  $data = json_decode($req->getBody());
  if (!$data or !is_string($data)) {
    $res->status(400); // Wrong message format
    $res['Content-Type'] = 'application/json; charset=utf-8';
    $res->body('{ "error": "Wrong message format (must be a JSON string)" }');
    return;
  }

如果我在第二行传入了一个0,$data仍然等于0。
在第三行,死在了!$data上。!$data是个很诡异的判断。
在PHP中,非0即true,0即false,”0″是false,’0’也是false。
就因为我写了一个0,便中了招,进入了报错代码块。

我们再来看一下第三行代码的意图: 如果非(false/0/null/未初始化/””/…) 或者 不是字符串的话,报错。
可是我单独打一个0,并不应该被算作非法输入。
那么改成什么好呢?

Salesfroce更新了Summer 16′ 版本的ForceIDE v37.0

官网地址:https://developer.salesforce.com/page/Force.com_IDE_Installation
更新日志:https://developer.salesforce.com/page/Force.com_IDE_Release_Notes

我在Eclipse Neon上已经成功更新。
本次更新的最大变更是。。。。更改了插件安装地址。没错。
还有提供了Lightning单独的开发组件。

另外,值得一提的是,启用了Java早就有的Open Type功能。

重点来了,打断点! Debug调式!没错!像个堂堂正正的Java程序员那样!
不过我还没试验这个新功能,之后会更新。