Luminus web项目默认会启用anti-forgery特性以防止跨站攻击,极大增强了安全性。但是也为一些异步发生(不是来源于服务端的输出页面)的请求(ajax)带来了不便。

可以如下解决之:

若你的网页模板是经由selmer layout的,它会自动带上这个anti-forgery token。你便可以在js中添加如下代码

```javascript

var csrfToken = "{{csrf-token}}";
$.ajaxPrefilter(function (options, originalOptions, request) {
if (csrfToken) {
request.setRequestHeader('X-CSRF-Token', csrfToken);
}
});
```

Luminus框架的anti-forgery middleware也可以接受http header中的"X-CSRF-Token"指定的token。
这样子就把token给带到服务端了。让ajax请求顺利发出。

用了clojure,才发现北方有一座高山……

今天网站中需要做一个小功能,通过restful api请求另外一个内部网站的数据,但是写这个网站的同学给出的数据是[[a b c] [d e f]...]另外还有一个用于代表每一项的链接的links: [link1 link2 link3...]

需要将之每项对应合并起来,找了下发现map-indexed非常适合这个场景:

```clojure
(def test1 [['a ] ['b] ['c]])
(def test2 ['c 'd 'e])
(defn my-merge [vect1 vect2]
(into [] (map-indexed
(fn [idx item] (merge item (vect2 idx))) vect1)))

(my-merge test1 test2)

=>[[a c] [b d] [c e]]
```

在一些复杂的JNI调用中,比如JNI调用Java层的对象、Java层又调native方法,嵌套过多了,某一次调用产生的异常会在下一次调用JNI时被check出来,
这时候会产生如下日志:

```bash
01-13 21:22:43.247 24613-24613/com.somepkg A/art: art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI NewByteArray called with pending exception 'java.lang.NullPointerException' thrown in unknown throw location
01-13 21:22:43.247 24613-24613/com.somepkg A/art: art/runtime/check_jni.cc:65] in call to NewByteArray
```

这种问题都是在Java代码中产生了异常,但是并不是所有case下都能一眼通过逻辑判断是哪行,这时候有个JNIEnv的方法能帮上我们大忙:
```c
jthrowable thr = (*env)->ExceptionOccurred(env);

if (thr) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
```

c++版本:
```c++
void CheckException(JNIEnv* env) {
if (!HasException(env)) return;

// Exception has been found, might as well tell breakpad about it.
jthrowable java_throwable = env->ExceptionOccurred();
if (!java_throwable) {
// Do nothing but return false.
CHECK(false);
}

// Clear the pending exception, since a local reference is now held.
env->ExceptionDescribe();
env->ExceptionClear();

// Set the exception_string in BuildInfo so that breakpad can read it.
// RVO should avoid any extra copies of the exception string.
base::android::BuildInfo::GetInstance()->set_java_exception_info(
GetJavaExceptionInfo(env, java_throwable));

// Now, feel good about it and die.
CHECK(false);
}
```

在被checkjni侦测到异常的代码(比如上例中是NewByteArray)之前加上如上代码就可以将Java层的异常信息给优雅地打印出来,从而精准定位问题。

另一种定位此类问题的方式是打开Android设备的CheckJni功能。但是一般production设备上都不太容易实现。所以强力推荐以上方法。

[environ](https://github.com/weavejester/environ)可以很方便帮我们管理项目中的各种配置,但是最近在使用的时候遇到了一个问题,就是我在dev, test profile下配置的database-uri到打出uberjar之后就访问不到了。最后看了下源码,在生产环境下,需要通过进程环境变量或Java系统属性来完成这一目的:

进程环境变量:

```bash
DATABASE_URL=jdbc:postgres://localhost/prod java -jar standalone.jar
```
Java系统属性:

```bash
java -Ddatabase.url=jdbc:postgres://localhost/prod -jar standalone.jar
```

最近遇到了一位很热心的用户,反映C208B011版本的Huawei X1(想想MediaPad系列本人几年前在华为也曾参与研发)上无法使用一个WebApp。debug后发现在该系统的WebView内的JS里无法使用console.log()导致严重的java-js之间的通信机制缺失。特意为其创建一个BridgePolicy类来维护之,若是该款机器,则切换至window.alert来实现java-js之间的通信,否则则使用console.log()。

测试发现该机器的C208B009版本的WebView并无此问题(且与硬件,基带是3G或4G均无关)。

第一次face to face面对我们的用户感触颇多,一个产品对于他们家里的人是如此重要,一个WebApp不能用又如此大程度的影响到他,因为存在这个问题甚至想换掉这部手机。

用户对于解决问题的意愿极强。他(40岁左右的大叔)多次上Huawei X1论坛与其他用户交流看法和规律,寻求解决方案,为此去了解该机器的CPU,基带,ROM版本......。

幸运的是,他们使用的是我们这个首屈一指的互联网公司的产品,遇到了我们这样的团队,得以面对面的反映他遇到的问题——没有抱怨,而是尽可能为我们提供他“调查”,“摸索”出来的规律。