当前位置: 首页>前端>正文

鸿蒙开发入门之让 httpRequest 支持 Cookie

浣滆€咃細鐜嬫櫒褰?/p>

鍓嶈█

瑕佽鏈€杩戝墠绔妧鏈湀浠€涔堟渶馃敟锛岄偅涓€瀹氶潪銆岄仴閬ラ鍏堛€嶇殑 Harmony OS 鑾睘锛屾湰鐫€瀵规柊鎶€鏈殑杩芥眰绮剧锛堟壎鎴戣捣鏉モ€︹€︼級锛屽挶浠篃鏉ュ皾璇曚竴涓嬨€?/p>

鎬濇潵鎯冲幓锛屽喅瀹氱敤楦胯挋閲嶅啓涓€涓嬩箣鍓嶇殑 Compose 鐗堟湰鐨勩€岀帺 Android銆嶃€?/p>

闂

瀵圭収鐫€瀹樻柟鏁欑▼锛屼竴寮€濮嬮兘鎸洪『鍒╋紝鐩村埌寮€濮嬪啓鐧诲綍妯″潡銆?/p>

鎴戜滑鐭ラ亾锛岄缚娲嬪ぇ浣殑銆岀帺 Android銆岮pi 鏄敤 Cookie 淇濆瓨鐧诲綍鐘舵€佺殑锛岃€岄缚钂欒姹傜綉缁滀娇鐢ㄧ殑 httpRequest 涓嶆敮鎸?Cookie锛屾垜缈婚亶浜嗗畼鏂规枃妗i兘娌℃壘鍒板叧浜?Cookie 鐨勮鏄庛€?/p>

鎴戜笉姝诲績锛屽績鎯筹紝Cookie 杩欎箞甯歌锛屽簲璇ヤ笉姝㈡垜涓€涓汉閬囧埌闂鍚э紝浜庢槸鍦ㄩ缚钂欏畼鏂瑰紑鍙戣€呰鍧涙悳绱?Cookie 鍏抽敭瀛楋紝杩樼湡鏈変汉鎻愰棶

鸿蒙开发入门之让 httpRequest 支持 Cookie,第1张

浜庢槸寮€蹇冪殑鐐逛簡杩涘幓锛岀湅鍒扮増涓荤殑鍥炵瓟鍚庯紝鎴戝交搴曟蹇冧簡馃挃

鸿蒙开发入门之让 httpRequest 支持 Cookie,第2张

鍏跺疄鑳藉鐞嗚В瀹樻柟涓轰粈涔堜笉鎻愪緵鐩存帴鎿嶄綔 Cookie 鐨勬帴鍙o紝鍥犱负杩欎釜澶€滀笟鍔♀€濅簡锛屽喌涓旓紝Android 瀹樻柟涔熸病鏈夋彁渚涚被浼肩殑鎺ュ彛锛岄渶瑕佸紑婧愮ぞ鍖哄府鍔╁畬鍠勩€?/p>

涓嶈繃鐩墠楦胯挋鐨勫紑婧愬簱灞堟寚鍙暟锛屼篃娌℃湁鎵惧埌缃戠粶鐩稿叧鐨勫紑婧愬簱銆?/p>

闅鹃亾 Harmony 鐗堟湰鐨勩€岀帺 Android銆嶅氨瑕佹姌鎴熶簬姝や簡鍚楋紝鎴栬€呬笉鎻愪緵鐧诲綍鍔熻兘锛?/p>

瑙e喅

淇楄瘽璇村緱濂斤細鍙鎬濇兂涓嶆粦鍧★紝鍔炴硶鎬绘瘮鍥伴毦澶氾紒鏃㈢劧娌℃湁鐜版垚鐨?Cookie 搴擄紝閭f垜浠氨鑷繁鏉ュ疄鐜颁竴涓€?/p>

鍥為【

鎴戜滑鍏堟潵澶嶄範涓?Cookie 鐨勭煡璇?/p>

瀹氫箟

鎽樿嚜缁村熀鐧剧

HTTP Cookie锛岀畝绉?Cookie锛屾槸娴忚缃戠珯鏃剁敱缃戠粶鏈嶅姟鍣ㄥ垱寤哄苟鐢辩綉椤垫祻瑙堝櫒瀛樻斁鍦ㄧ敤鎴疯绠楁満鎴栧叾浠栬澶囩殑灏忔枃鏈枃浠躲€?

缁撴瀯

Cookie鐨勫熀鏈粨鏋勫寘鎷?/p>

  1. 鍚嶇О
  2. 鍙栧€?/li>
  3. 鍚勭灞炴€?/li>

灞炴€?/strong>

涓€鏉?Cookie 鍙兘鏈?Domain銆?code>Path銆?code>Expires銆?code>Max-Age銆?code>Secure銆?code>HttpOnly 绛夊绉嶅睘鎬э紝濡?/p>

HTTP/1.0 200 OK
Set-Cookie: LSID=DQAAAK鈥aem_vYg; Path=/accounts; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly
Set-Cookie: HSID=AYQEVn鈥Krdst; Domain=.foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly
Set-Cookie: SSID=Ap4P鈥TEq; Domain=foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly
鈥?

宸ヤ綔娴佺▼

  1. 瀹㈡埛绔姹傛湇鍔″櫒鏃讹紝鏈嶅姟鍣ㄩ€氳繃鍝嶅簲澶翠腑鐨?Set-Cookie 鍏抽敭瀛楀憡璇夊鎴风闇€瑕佷繚瀛樼殑 Cookie 淇℃伅
  2. 瀹㈡埛绔牴鎹?Cookie 绫诲瀷淇濆瓨 Cookie 淇℃伅
  3. 涓嬫璇锋眰鏃舵鏌ュ綋鍓?Domain 鍜?Path 鍦ㄦ湰鍦版槸鍚︽湁 Cookie 淇℃伅锛屽鏋滄湁鐨勮瘽锛岄€氳繃璇锋眰澶翠腑鐨?Cookie 瀛楁灏?Cookie 淇℃伅鍛婅瘔鏈嶅姟鍣?/li>

鍚彂

鏃㈢劧 Cookie 鐨勬帴鏀跺拰鍙戦€侀兘鏄€氳繃 Header 瀹炵幇锛岄偅鎴戜滑涔熷彲浠ヤ粠杩欓噷鍏ユ墜銆?/p>

鍏堢湅鎺ユ敹閮ㄥ垎锛屾垜浠厛鐢?PostMan 鍙戦€佽姹傦紝鐪嬩笅杩斿洖鐨?Cookie锛屼綔涓哄鐓?/p>

鸿蒙开发入门之让 httpRequest 支持 Cookie,第3张

鍙互鐪嬪埌锛岀櫥褰曚俊鎭繚瀛樺湪浜?loginUserName 鍜?token_pass 涓?/p>

鎺ヤ笅鏉ワ紝鎴戜滑鎵撳嵃涓嬬敤 httpRequest 鍙戦€佺櫥褰曡姹傜殑鍝嶅簲澶?/p>

{
    "content-type": "application/json;charset=UTF-8",
    "date": "Wed, 27 Dec 2023 07:50:12 GMT",
    "server": "Apache-Coyote/1.1",
    "set-cookie": "token_pass_wanandroid_com=******; Domain=wanandroid.com; Expires=Fri, 26-Jan-2024 07:50:12 GMT; Path=/",
    "transfer-encoding": "chunked"
}

濂藉浼欙紝鎬庝箞鍙湁 token_pass锛岄缚钂欎綘璁╂垜璇翠綘浠€涔堝ソ锛屾€庝箞 Cookie 杩樺皯浜?/p>

濂藉湪鎴戝彂鐜?httpRequest 鐨?Response 涓湁涓€涓崟鐙殑 Cookie 瀛楁锛屾墦鍗颁笅鐪嬬湅

www.wanandroid.com  FALSE   /   FALSE   1706255412  loginUserName   chaywong
www.wanandroid.com  FALSE   /   FALSE   1706255412  token_pass  xxxxxx
.wanandroid.com TRUE    /   FALSE   1706255412  loginUserName_wanandroid_com    chaywong
.wanandroid.com TRUE    /   FALSE   1706255412  token_pass_wanandroid_com   xxxxxx
#HttpOnly_www.wanandroid.com    FALSE   /   TRUE    0   JSESSIONID  CDF02AE9203F644EF8E44F8C444AD3B1

杩欐鍊掓槸鍩烘湰鍏ㄤ簡锛屼竴涓崲琛岃〃绀轰竴鏉?Cookie锛屾瘡涓€琛岄€氳繃绌烘牸闅斿紑 Cookie 鐨勫睘鎬э紝鍙槸杩欐瘡涓睘鎬ф槸浠€涔堝惈涔夊晩锛?/p>

鍙堟槸涓€椤跨炕鏂囨。锛岀炕娉ㄩ噴锛屼篃娌℃壘鍒版瘡涓瓧娈电殑璇存槑锛岀湅鏉ュ彧鑳界‖鐫€澶寸毊鐚滀簡

鍏堢湅绗竴琛岋紝wanandroid.com 搴旇鏄?Domain锛?code>/ 搴旇鏄?Path锛?code>1706255412 搴旇鏄繃鏈熸椂闂达紝loginUserName 杩欒鏄?Cookie name锛?code>chaywong 鏄垜鐨勭敤鎴峰悕锛屾墍浠ヨ繖涓簲璇ユ槸 Cookie value锛屽墿涓嬬殑涓や釜 boolean 瀹炲湪娌℃硶鐚滀簡锛屽簲璇ユ槸 Secure 鍜?HttpOnly锛屼絾鏄病鍔炴硶瀵瑰簲銆?/p>

濂藉湪杩欎袱涓睘鎬у苟涓嶉噸瑕侊紝涓嶅奖鍝嶄富瑕佸姛鑳姐€?/p>

鏈変簡鏈嶅姟鍣ㄧ殑 Cookie锛屾垜浠繕瑕佹妸 Cookie 鍐嶅彂閫佺粰鏈嶅姟鍣紝浠ヨ〃鏄庤韩浠斤紝杩欏氨鏇寸畝鍗曚簡

鐩存帴鍦?httpRequest 鐨勮姹傚ご涓鍔?Cookie 瀛楁锛屾牸寮忎负

name1=value1; name2=value2

瀹炶返

鏃㈢劧 Cookie 鐨勬帴鏀跺拰鍙戦€侀兘娌¢棶棰樹簡锛岄偅鎴戜滑灏辨潵瀹炵幇涓€涓缚钂欎笂鐨?CookieJar锛?/p>

涓轰簡灏戣蛋寮矾锛屽疄璺甸儴鍒嗘垜浠洿鎺ュ弬鑰?Android 涓婄殑鏈夊悕鐨勫紑婧愬簱 PersistentCookieJar 锛屽拰 OkHttp 閰嶅悎璧锋潵浣跨敤 Cookie 闈炲父鏂逛究锛屾垜鍦?Compose 鐗堢殑銆岀帺 Android銆?涓婄敤鐨勪篃鏄繖涓柟妗堛€?/p>

棣栧厛瀹氫箟 Cookie 瀵硅薄锛岀敤鏉ヤ繚瀛?Cookie 灞炴€э紝OkHttp 涓凡缁忓畾涔夊ソ浜嗭紝鎴戜滑鐩存帴鎷挎潵鐢?/p>

鸿蒙开发入门之让 httpRequest 支持 Cookie,第4张

杞垚 TS 鐗堟湰

/**
 * Cookie 瀵硅薄锛屽弬鑰?OkHttp 涓?Cookie 缁撴瀯
 */
export default class Cookie {
  name: string = "";
  value: string = "";
  expiresAt: number = 0;
  domain: string = "";
  path: string = "";
  httpOnly: boolean = false;
  persistent: boolean = true;

  matches(url: uri.URI): boolean {
    let domainMatch = Cookie.domainMatch(url.host, this.domain);
    if (!domainMatch) return false;
    if (!Cookie.pathMatch(url, this.path)) return false;
    return true;
  }

  createCookieKey(): string {
    return `https://${this.domain}${this.path}|${this.name}`;
  }

  isExpired(): boolean {
    let nowTime = Date.now() / 1000;
    return this.expiresAt < nowTime;
  }
}

鏈変簺灞炴€ф垜浠殏鏃惰幏鍙栦笉鍒帮紝鍙互鍏堝拷鐣ャ€?/p>

鎺ヤ笅鏉ユ槸瑙f瀽 httpRequest Response 涓殑 Cookie 淇℃伅

/**
 * httpRequest 杩斿洖鐨?cookie 鏍煎紡锛?
 * ```
 * www.wanandroid.com   FALSE   /   FALSE   1706255412  loginUserName   chaywong
 * www.wanandroid.com   FALSE   /   FALSE   1706255412  token_pass  xxxxxx
 * .wanandroid.com  TRUE    /   FALSE   1706255412  loginUserName_wanandroid_com    chaywong
 * .wanandroid.com  TRUE    /   FALSE   1706255412  token_pass_wanandroid_com   xxxxxx
 * #HttpOnly_www.wanandroid.com FALSE   /   TRUE    0   JSESSIONID  CDF02AE9203F644EF8E44F8C444AD3B1
 * ```
 */
static parseHttpRequestCookies(cookieString: string): Array<Cookie> {
  if (!cookieString) return [];
  let cookies: Array<Cookie> = [];
  let lines = cookieString.split("\r\n");
  lines.forEach((line) => {
    let attrs = line.split("\t");
    if (attrs.length !== 7 || !attrs[0]) return;
    let cookie = new Cookie();
    let domain = attrs[0];
    if (domain.startsWith("#HttpOnly_")) {
      domain = domain.substring("#HttpOnly_".length);
      cookie.httpOnly = true;
    }
    cookie.domain = domain;
    cookie.path = attrs[2];
    cookie.expiresAt = parseInt(attrs[4]);
    cookie.name = attrs[5];
    cookie.value = attrs[6];
    cookies.push(cookie);
  })
  return cookies;
}

鎺ヤ笅鏉ユ槸璁捐 CookieJar锛屽疄鐜?Cookie 鐨勬帴鏀躲€佸彂閫佸姛鑳斤紝杩欓噷鎴戜滑鍚屾牱鍊熼壌 OkHttp 鐨?CookieJar 鎺ュ彛锛岃繖鍑犱釜鎺ュ彛鍒氬ソ婊¤冻鎴戜滑鎺ユ敹銆佸彂閫併€佹竻闄?Cookie 鐨勮兘鍔涖€?/p>

鸿蒙开发入门之让 httpRequest 支持 Cookie,第5张
鸿蒙开发入门之让 httpRequest 支持 Cookie,第6张

杞垚 TS 鐗堟湰

export default interface CookieJar {
  init(): Promise<void>;

  saveFromResponse(url: uri.URI, cookies: Array<Cookie>);

  loadForRequest(url: uri.URI): Array<Cookie>;

  clear();
}

澧炲姞浜嗕竴涓?init 寮傛鏂规硶涓昏鏄负浜嗗紓姝ュ姞杞?KV 缂撳瓨銆?/p>

鎺ュ彛瀹氫箟濂斤紝鎺ヤ笅鏉ュ氨鏄疄鐜颁簡锛岃繖涓嬭鍙傝€?PersistentCookieJar 浜?/p>

鸿蒙开发入门之让 httpRequest 支持 Cookie,第7张

杩欓噷涓昏閫氳繃鍐呭瓨鍜?Preference 鍙岄噸缂撳瓨 Cookie 淇℃伅锛岄€昏緫骞朵笉澶嶆潅锛屾垜浠洿鎺ュ疄鐜?TS 鐗堟湰

export default class PersistentCookieJar implements CookieJar {
  private isInit = false;
  private cache: HashMap<string, Cookie> = new HashMap();
  private persistor: CookiePersistor;

  constructor(context: Context) {
    this.persistor = new KVCookiePersistor(context);
  }

  async init(): Promise<void> {
    if (!this.isInit) {
      let cookies = await this.persistor.loadAll();
      cookies.forEach((cookie) => {
        this.cache.set(cookie.createCookieKey(), cookie);
      })
      this.isInit = true;
    }
    return new Promise<void>((resolve, reject) => {
      resolve();
    })
  }

  saveFromResponse(url: uri.URI, cookies: Cookie[]) {
    cookies.forEach((cookie) => {
      this.cache.set(cookie.createCookieKey(), cookie);
    })
    this.persistor.saveAll(PersistentCookieJar.filterPersistentCookies(cookies));
  }

  private static filterPersistentCookies(cookies: Array<Cookie>): Array<Cookie> {
    return cookies.filter((item) => {
      return item.persistent;
    })
  }

  loadForRequest(url: uri.URI): Cookie[] {
    let cookiesToRemove: Array<Cookie> = [];
    let validCookies: Array<Cookie> = [];

    let iterator: IterableIterator<Cookie> = this.cache.values();
    let result = iterator.next();
    while (!result.done) {
      let currentCookie: Cookie = result.value;
      if (currentCookie.isExpired()) {
        cookiesToRemove.push(currentCookie);
      } else if (currentCookie.matches(url)) {
        validCookies.push(currentCookie);
      }
      result = iterator.next();
    }

    cookiesToRemove.forEach((item) => {
      this.cache.remove(item.createCookieKey());
    })

    this.persistor.removeAll(cookiesToRemove);

    return validCookies;
  }

  clear() {
    this.cache.clear();
    this.persistor.clear();
  }
}

TS 鐗堢殑 KV 缂撳瓨 KVCookiePersistor 鐨勫叿浣撳疄鐜拌繖閲屽厛鐪佺暐浜嗭紝鍚庨潰璐村畬鏁翠唬鐮併€?/p>

鍒拌繖閲岋紝鎴戜滑宸茬粡瀹炵幇浜嗛缚钂欑増鐨?CookieJar 浜嗭紝鍙渶瑕佸拰 httpRequest 缁撳悎璧锋潵鍗冲彲

鎴戞娊浜嗕竴涓叕鍏辩殑鍙戦€佽姹傜殑鏂规硶锛屽彧闇€瑕佸湪杩欓噷鍔犱笂 CookieJar 鐨勮皟鐢ㄥ嵆鍙€?鍦ㄨ姹傚墠鏌ユ壘鏄惁鏈夊尮閰嶇殑 Cookie锛屽鏋滄湁灏辨坊鍔犲埌 Header 涓紝鍚屾牱鐨勫湪璇锋眰杩斿洖鍚庡瓨鍌ㄦ湇鍔$杩斿洖鐨?Cookie 淇℃伅銆?/p>

let cookieJar: CookieJar = new PersistentCookieJar(EntryContext.getContext());

/**
 * 閫氱敤璇锋眰鏂规硶
 */
async function requestSync<T>(path: string, method: http.RequestMethod, extraData?: Object): Promise<Response<T>> {
  // 纭繚 CookieJar 宸茬粡鍒濆鍖?
  await cookieJar.init();
  return new Promise<Response<T>>((resolve, reject) => {
    let url = BASE_URL + path;
    let uri = parseUri(url);
    let header = {};
    // 鏍规嵁 url 鍔犺浇鏈湴缂撳瓨鐨?Cookie
    let cookies = cookieJar.loadForRequest(uri);
    if (cookies.length > 0) {
      // 灏?Cookie 娣诲姞鍒?Header 涓?
      header["Cookie"] = CookieUtils.cookieHeader(cookies);
    }
    if (method === http.RequestMethod.POST) {
      header["Content-Type"] = "application/x-www-form-urlencoded";
    }
    let httpRequest = http.createHttp();
    httpRequest.request(
      url,
      {
        method: method,
        expectDataType: http.HttpDataType.OBJECT,
        header: header,
        extraData: extraData
      },
      (err, data) => {
        let res = new Response<T>()
        if (!err && data.responseCode === 200) {
          // 璇锋眰鎴愬姛锛屼繚瀛樻湇鍔$杩斿洖鐨?Cookie
          cookieJar.saveFromResponse(uri, CookieUtils.parseHttpRequestCookies(data.cookies))
          Object.assign(res, data.result)
        } else {
          res.errorCode = data.responseCode
          res.errorMsg = err.message
        }
        resolve(res);
      }
    )
  })
}

/**
 * 鐧诲綍璇锋眰
 */
async login(username: string, password: string): Promise<Response<User>> {
  return requestSync("/user/login", http.RequestMethod.POST, `username=${username}&password=${password}`);
}

杩愯椤圭洰锛岀櫥褰曚竴涓嬶紝鎴戜滑鐨勭櫥褰曠姸鎬佹灉鐒惰淇濆瓨涓嬫潵浜嗭紝鐢变簬閫氳繃 KV 鎸佷箙鍖栦簡 Cookie 淇℃伅锛岄噸鍚?App 鍚庣櫥褰曟€佷粛鐒惰繕鍦ㄣ€?/p>

鎬荤粨

鏈枃涓昏鍒嗕韩鍦ㄥ叆鍧戦缚钂欐椂閬囧埌鐨?Cookie 闂锛岄€氳繃鍊熼壌 Android 涓婄殑 OkHttp锛屾渶缁堝疄鐜颁簡楦胯挋鐗堢殑 PersistentCookieJar锛岃櫧鐒跺姛鑳戒笉澶熷畬鍠勶紝浣嗗凡缁忚兘澶熻В鍐抽棶棰橈紝鏈熼棿涔熻杩涔犱簡涓€鎶婄綉缁滅煡璇嗐€?/p>


https://www.xamrdz.com/web/2c71995284.html

相关文章: