如何解决在Roku上提出要求后,没有看到任何Cookie
我有一个Roku应用,它将在视频播放时对后端服务进行几次异步调用。 可能 其中的某些通话可能会同时发生。这些调用都依赖Cookie进行身份验证。
由于调用依赖于Cookie进行身份验证,因此我需要利用单个roUrlTransfer
对象。如果我为每个请求创建一个新的roUrlTransfer
实例,则它们将不会共享Cookie缓存
但是,因为可能同时发生两个调用,所以我不能使用单个roUrlTransfer
对象。根据{{3}}:
每个roUrlTransfer对象一次只能执行一个异步操作。启动异步操作后,您将无法使用该对象执行任何其他数据传输操作,直到异步操作完成为止(如收到roUrlEvent消息所示),该消息的GetSourceIdentity值与roUrlTransfer的GetIdentity值相匹配。
要解决这两个问题,我创建了一个包装对象。我维护一个称为“ cookieJar”的单例roUrlTransfer
对象,然后每个请求启动一个新的roUrlTransfer
实例:
' ********************************************************************
' ** URL class to streamline adding query parameters and making requests.
' ********************************************************************
Function Downloader() As Object
return {
Send: Downloader_Send
AsyncWait: Downloader_AsyncWait
}
End Function
Function CookieJar() As Object
if m.cookiejar = invalid
m.cookiejar = CreateObject("roUrlTransfer")
m.cookiejar.EnableCookies()
end if
return m.cookiejar
End Function
Function Downloader_Send(req={} As Object)
if req.url <> invalid
m.req = req
m.http = CreateObject("roUrlTransfer")
m.port = CreateObject("roMessagePort")
m.http.SetPort(m.port)
m.http.EnableEncodings(true)
' ParseURL is a helper function I wrote that just breaks a URL into
' its components: scheme,host,path,query,and fragment
m.url = ParseURL(req.url)
m.http.EnableCookies()
m.http.AddCookies(CookieJar().GetCookies(m.url.host,m.url.path))
m.http.SetUrl(req.url)
if req.method <> invalid
m.http.SetRequest(req.method)
else
m.http.SetRequest("GET")
end if
if req.timeout <> invalid
m.timeout = req.timeout
else
m.timeout = 5000
end if
data = {}
if req.body <> invalid
if m.http.AsyncPostFromString(FormatJSON(req.body))
data = m.AsyncWait()
end if
else
if m.http.AsyncGetToString()
data = m.AsyncWait()
end if
end if
end if
return data
End Function
Function Downloader_AsyncWait() As Dynamic
event = wait(m.timeout,m.port)
if type(event) = "roUrlEvent"
print "Headers:"
print event.GetResponseHeaders()
print "Adding cookies to cookie jar:"
print m.http.GetCookies(m.url.host,m.url.path)
print m.http.GetCookies("","/")
CookieJar().AddCookies(m.http.GetCookies(m.url.host,m.url.path))
return {
statusCode: event.GetResponseCode()
error: event.getFailureReason()
body: event.GetString()
headers: event.GetResponseHeaders()
}
else if event = invalid
m.http.AsyncCancel()
end if
return invalid
End Function
为了测试我的代码,我启动了一个非常简单的ExpressJS服务器,该服务器除了设置cookie外什么也不做:
var express = require("express");
var cookieParser = require("cookie-parser");
var app = express();
app.use(cookieParser());
app.get("/",function (req,res) {
res.cookie("key","value",{
domain: "192.168.1.102:3333",path: "/",expire: Date.now() + 3600000
});
res.send("Done");
});
var server = app.listen(3333,function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s",port);
});
然后在我的Roku应用程序中(在主屏幕上),我有以下内容:
httpClient = Downloader()
httpClient.Send({
' My local IP address
url: "http://192.168.1.102:3333"
})
在Roku上运行此命令时,在调试日志中看到以下内容:
Headers:
<Component: roAssociativeArray> =
{
connection: "keep-alive"
content-length: "13"
content-type: "text/html; charset=utf-8"
date: "Tue,11 Aug 2020 17:29:52 GMT"
etag: "W/"d-w+Ote5otCKx40dtR446Vz7wX66U""
set-cookie: "key=value; Path=/"
x-powered-by: "Express"
}
Adding cookies to cookie jar:
<Component: roArray> =
[
]
<Component: roArray> =
[
]
m.http.GetCookies(m.url.host,m.url.path)
和m.http.GetCookies("","/")
均未返回任何cookie。但是您可以在标题中清楚地看到Cookie!那我为什么不能访问它?
请注意,m.url.host
为192.168.1.102:3333
,m.url.path
为
(空白),以防万一。
解决方法
经过一整天的研究,我发现Roku无法正确处理Cookie域中的 端口 。当192.168.1.102:3333
提供Cookie时,Roku在内部将Cookie标记为属于192.168.1.102
(无端口)。
这有两个含义:
- 如果为cookie提供了
...; domain=...;
属性,并且该域包含端口,则Roku完全无法解析set-cookie
标头,并且不会提取任何cookie - 如果不提供此属性,则Roku将解析
set-cookie
标头,但是GetCookies()
仅在没有域的情况下返回cookie({{1} }或指定了无端口域。""
返回cookie,但GetCookies("192.168.1.102","/")
不返回
因为我的代码的目的是在多个roUrlTransfer实例之间共享Cookie,所以可以使用GetCookies("192.168.1.102:3333","/")
获取所有 Cookie,因此我们将修改后端以删除GetCookies("","/")
标头中的...; domain=...;
属性
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。