React.js学习一席AndroidReact Native开发

React Native Cookie使用指南

2016-11-19  本文已影响6739人  ronniegong

React Native Cookie使用指南

web开发中,cookie是一个常用工具。通常会将用户与服务器会话的sessionid存储在cookie中,用以在请求中标示会话来源。或者将登录态token值存储在cookie中,请求中通过cookie值校验登录态。

当我们使用react native开发应用时,是否还能像在web开发中那样使用cookie呢?官方文档中没有相关资料,需要我们自己去探索。

场景探索

本文采用react native 0.35版本,针对以下场景进行了探索

原理分析

上述场景中可见,react native对cookie支持度还是很高的。那么这个支持是如何实现的呢?带着这个问题,笔者阅读了react-native-cookiemanager的源码。

笔者没有原生客户端开发经验,是通过阅读代码,发现实际在客户端,android和ios各有原生api支持对cookie的操作。并且,通过查阅资料,了解到安卓和ios端,分别会将cookie以文件形式持久化,这也是为什么再次进入应用中,仍然能获取到cookie值的原因。

react-native-cookiemanager安卓端关键代码

@ReactMethod
    public void setCookie(ReadableMap options) {
        String name = null;
        String value = null;
        String domain = null;
        String origin = null;
        String path = null;
        String expiration = null;
        if (options.hasKey(OPTIONS_NAME)) {
            name = options.getString(OPTIONS_NAME);
        }
        if (options.hasKey(OPTIONS_VALUE)) {
            value = options.getString(OPTIONS_VALUE);
        }
        if (options.hasKey(OPTIONS_DOMAIN)) {
            domain = options.getString(OPTIONS_DOMAIN);
        }
        if (options.hasKey(OPTIONS_ORIGIN)) {
            origin = options.getString(OPTIONS_ORIGIN);
        }
        if (options.hasKey(OPTIONS_PATH)) {
            path = options.getString(OPTIONS_PATH);
        }
        if (options.hasKey(OPTIONS_EXPIRATION)) {
            expiration = options.getString(OPTIONS_EXPIRATION);
        }
        CookieManager.getInstance().setCookie(origin, name + "=" + value + ";"
                + OPTIONS_PATH + "=" + path + ";"
                + OPTIONS_EXPIRATION + "=" + expiration + ";"
                + OPTIONS_DOMAIN + "=" + domain);
    }

    /**
     * Gets the cookies for the given URL.
     *
     * @param url the URL for which the cookies are requested
     * @return value the cookies as a string, using the format of the 'Cookie'
     * HTTP request header
     */
    @ReactMethod
    public void getCookie(String url, Callback callback) {
        String cookie = CookieManager.getInstance().getCookie(url);
        callback.invoke(cookie);
    }

    @ReactMethod
    public void removeAllCookies() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            CookieManager.getInstance().removeAllCookies(new ValueCallback<Boolean>() {
                @Override
                public void onReceiveValue(Boolean value) {
                }
            });
        } else {
            CookieManager.getInstance().removeAllCookie();
        }
    }

react-native-cookiemanager ios端关键代码

RCT_EXPORT_METHOD(setCookie:(NSDictionary *)props) {
    NSString *name = [RCTConvert NSString:props[@"name"]];
    NSString *value = [RCTConvert NSString:props[@"value"]];
    NSString *domain = [RCTConvert NSString:props[@"domain"]];
    NSString *origin = [RCTConvert NSString:props[@"origin"]];
    NSString *path = [RCTConvert NSString:props[@"path"]];
    NSDate *expiration = [RCTConvert NSDate:props[@"expiration"]];

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:name forKey:NSHTTPCookieName];
    [cookieProperties setObject:value forKey:NSHTTPCookieValue];
    [cookieProperties setObject:domain forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:origin forKey:NSHTTPCookieOriginURL];
    [cookieProperties setObject:path forKey:NSHTTPCookiePath];
    [cookieProperties setObject:expiration forKey:NSHTTPCookieExpires];

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}


RCT_EXPORT_METHOD(clearAll:(RCTResponseSenderBlock)callback) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *c in cookieStorage.cookies) {
        [cookieStorage deleteCookie:c];
    }
    callback(@"success");
}

// TODO: return a better formatted list of cookies per domain
RCT_EXPORT_METHOD(getAll:(RCTResponseSenderBlock)callback) {
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSMutableDictionary *cookies = [NSMutableDictionary dictionary];
    for (NSHTTPCookie *c in cookieStorage.cookies) {
        NSMutableDictionary *d = [NSMutableDictionary dictionary];
        [d setObject:c.value forKey:@"value"];
        [d setObject:c.name forKey:@"name"];
        [d setObject:c.domain forKey:@"domain"];
        [d setObject:c.path forKey:@"path"];
        [cookies setObject:d forKey:c.name];
    }
    callback(@[cookies, @"success"]);
}

最后

在场景三中有一点笔者是有疑问的,就是当cookie值没有设置过期时间、或者设置一个已经失效的时间时,安卓端也会将这一cookie值持久化,使得再次进入应用中还能获取到。

按照一般理解,没有设置过期时间时,调用setCookie保存cookie,及将cookie持久化时,应该像ios端一样,将这一cookie值丢弃。但是在跟进调试上述代码时,在CookieManager.getInstance().setCookie处的断点进入到的是一个抽象方法,没有进入到实现中,这一疑问有待进一步研究,欢迎安卓端有经验的朋友指导。

如果觉得有帮助,可以扫描二维码对我打赏,谢谢

上一篇 下一篇

猜你喜欢

热点阅读