首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Indy 10 -手动添加cookie

Indy 10 -手动添加cookie
EN

Stack Overflow用户
提问于 2021-10-26 14:29:44
回答 1查看 116关注 0票数 0

我可以使用谷歌Chrome的"EditThisCookie“导出我的饼干。

出口情况如下:

代码语言:javascript
复制
"domain": ".stackoverflow.com",
"expirationDate": 1698322697,
"hostOnly": false,
"httpOnly": false,
"name": "_ga",
"path": "/",
"sameSite": "unspecified",
"secure": false,
"session": false,
"storeId": "0",
"value": "some",
"id": 1    

现在,我希望将此字符串存储/解析到现有的TIdHTTP Cookie管理器中。

如何使用TIdCookie将这些值添加到Cookie管理器

这就是我试过的,没有运气:

代码语言:javascript
复制
procedure ImportCookies (JSONCookies: string; CookieManager: TIdCookieManager);
var
  StringList: TStringList;
  I : Integer;
  InCookie : Boolean;
  MyCookie: TidCookie;
    
  function BoolStrToBool(s: string): Boolean;
  begin
    if Copy(UpperCase(Trim(s)), 1, 4) = 'TRUE' then Exit(True) else Exit(False);
  end;
    
begin
  InCookie         := False;
  StringList       := TStringList.Create;
  try
    StringList.Text:= JSONCookies;
    for I := 0 to StringList.Count - 1 do
    begin
      if Trim(StringList.Strings[i]) = '{' then
      begin
        InCookie := True;
        MyCookie := CookieManager.CookieCollection.Add;
        Continue;
      end;
    
      if (Trim(StringList.Strings[i]) = '}') or (Trim(StringList.Strings[i]) = '},') then
      begin
        InCookie := False;
        Continue;
      end;
    
      if InCookie then
      begin
        if Copy(StringList.Strings[i], 1, 9) = '"domain":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 10, MaxInt);
          MyCookie.Domain := GetBetween(StringList.Strings[i], '"', '"');
          Continue;
        end;
        if Copy(StringList.Strings[i], 1, 11) = '"hostOnly":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 12, MaxInt);
          MyCookie.HostOnly := BoolStrToBool(StringList.Strings[i]);
          Continue;
        end;
        if Copy(StringList.Strings[i], 1, 11) = '"httpOnly":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 12, MaxInt);
          MyCookie.HttpOnly := BoolStrToBool(StringList.Strings[i]);
          Continue;
        end;
        if Copy (StringList.Strings[i], 1, 7) = '"name":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 8, MaxInt);
          MyCookie.CookieName := GetBetween(StringList.Strings[i], '"', '"');
          Continue;
        end;
        if Copy(StringList.Strings[i], 1, 7) = '"path":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 8, MaxInt);
          MyCookie.Path := GetBetween(StringList.Strings[i], '"', '"');
          Continue;
        end;
        if Copy(StringList.Strings[i], 1, 9) = '"secure":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 10, MaxInt);
          MyCookie.Secure := BoolStrToBool(StringList.Strings[i]);
          Continue;
        end;
        if Copy(StringList.Strings[i], 1, 8) = '"value":' then
        begin
          StringList.Strings[i] := Copy(StringList.Strings[i], 9, MaxInt);
          MyCookie.Path := GetBetween(StringList.Strings[i], '"', '"');
          Continue;
        end;
      end;
    end;
  finally
    StringList.Free;
  end;
end;           

我不明白为什么我需要一个TIdURI实例--起源应该无关紧要,因为已经有目的地域了?!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-26 17:32:48

FYI,如果使用实际的JSON解析器以及现有的RTL/库函数,可以大大简化代码,例如:

  • StrUtils.StartsText()IdGlobal.TextStartsWith()
  • SysUtils.StrToBool()
  • SysUtils.AnsiExtractQuotedStr()IdGlobalProtocols.UnquotedStr()
  • IdGlobal.PosInStrAray()
  • etc.

或者,您可以简单地将导出的cookie数据重新格式化为标准的HTTP格式,然后让TIdCookieManager.AddServerCookie()为您完成所有的解析(但随后需要一个TIdURI)。

在任何情况下,TIdURI都是由TIdCookieManager的解析器使用的,因为cookie的某些方面需要根据它的来源进行验证。例如,当确定cookie的路径时,或者将其与域/主机匹配,或者甚至仅仅知道HostOnly cookie的源主机是什么,或者HttpOnly cookie是否通过HTTP接收到等等。

在您的例子中,由于您跳过了TIdCookieManager.AddServerCookie(),所以您并不需要TIdURI,因为Chrome已经为您完成了繁重的处理。

但是,AddServerCookie()确实做了一件事情,而您没有这样做,那就是它将TIdCookie添加到内部TIdCookies列表中,稍后在决定将哪些cookie发送回TIdHTTP请求中的哪个服务器时使用该列表(请参阅TIdCookieManager.GenerateClientCookies())。

因此,仅仅调用TIdCookieManager.CookieCollection.Add()是不够的,它只创建TIdCookie对象。您还需要调用TIdCookieManager.CookieCollection.AddCookie() --这也需要一个TIdURI,尽管这个是可选的,而AddServerCookie()中的那个是必需的。

所以,尝试更像这样的东西:

代码语言:javascript
复制
procedure ImportCookies(JSONCookies: string; CookieManager: TIdCookieManager);
var
  StringList: TStringList;
  I : Integer;
  MyCookie: TidCookie;
  S, FieldName, FieldValue: string;

  procedure AddMyCookieIfReady;
  begin
    if MyCookie <> nil then
    begin
      if not CookieManager.CookieCollection.AddCookie(MyCookie, nil) then
      begin
        MyCookie.Collection := nil;
        MyCookie.Free;
      end;
      MyCookie = nil;
    end;
  end;

begin
  StringList := TStringList.Create;
  try
    StringList.Text := JSONCookies;
    MyCookie := nil;

    for I := 0 to StringList.Count - 1 do
    begin
      s := Trim(StringList.Strings[I]);

      if s = '{' then
      begin
        AddMyCookieIfReady;
        MyCookie := CookieManager.CookieCollection.Add;
        Continue;
      end;
    
      if TextStartsWith(s, '}') then
      begin
        AddMyCookieIfReady;
        Continue;
      end;
    
      if (MyCookie = nil) or (not TextStartsWith(s, '"')) then
        Continue;

      Delete(s, 1, 1);
      FieldName := Fetch(s, '"');
      Fetch(s, ':');
      FieldValue := UnquotedStr(TrimLeft(s));

      case PosInStrArray(FieldName, ['domain', 'hostOnly', 'httpOnly', 'name', 'path', 'secure', 'value'], False) of
        0: begin
          if TextStartsWith(FieldValue, '.') then Delete(FieldValue, 1, 1);
          MyCookie.Domain := FieldValue;
        end;
        1: MyCookie.HostOnly := StrToBool(FieldValue);
        2: MyCookie.HttpOnly := StrToBool(FieldValue);
        3: MyCookie.CookieName := FieldValue;
        4: MyCookie.Path := FieldValue;
        5: MyCookie.Secure := StrToBool(FieldValue);
        6: MyCookie.Value := FieldValue;
      end;
    end;

    AddMyCookieIfReady;
  finally
    StringList.Free;
  end;
end;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69725011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档