我可以使用谷歌Chrome的"EditThisCookie“导出我的饼干。
出口情况如下:
"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管理器
这就是我试过的,没有运气:
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实例--起源应该无关紧要,因为已经有目的地域了?!
发布于 2021-10-26 17:32:48
FYI,如果使用实际的JSON解析器以及现有的RTL/库函数,可以大大简化代码,例如:
StrUtils.StartsText()或IdGlobal.TextStartsWith()SysUtils.StrToBool()SysUtils.AnsiExtractQuotedStr()或IdGlobalProtocols.UnquotedStr()IdGlobal.PosInStrAray()或者,您可以简单地将导出的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()中的那个是必需的。
所以,尝试更像这样的东西:
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;https://stackoverflow.com/questions/69725011
复制相似问题