Тема: AHK: Не применяется SetRequestHeader в Msxml2.XMLHTTP
Пытаюсь сделать для себя что-то подобие Fetch у JS, и проблема возникла с "мультипоточным" запросом.
Информация о нем: https://www.autohotkey.com/boards/viewt … 247#p34247.
На хостинг приходят запросы, но "User-Agent" не меняется, с "WinHttp.WinHttpRequest.5.1" такого нет.
Лог с сервера:
::1 - - [07/May/2021:01:32:58 +0000] "GET /ahk HTTP/1.1" 200 425 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)"
Вот мой класс (на сколько я помню, там нет доп функций кроме библиотеки JSON):
class Fetch
{
__New(resource, init := "", callback := "")
{
if (init == "")
{
init := {}
}
this.resource := resource
this.method := (init.method ? init.method : "GET")
this.headers := (init.headers ? init.headers : {})
this.applyHeaedrs := {}
this.body := (init.body ? init.body : "")
this.callback := callback
this.isSend := 0
if (this.body)
{
json := JSON.Stringify(this.body)
if (strLen(json) > 2)
{
this.body := json
}
}
if (!callback)
{
this.Request := ComObjCreate("WinHttp.WinHttpRequest.5.1")
this.Request.Open(this.method, this.resource, false)
}
else
{
this.Request := ComObjCreate("Msxml2.XMLHTTP")
this.Request.Open(this.method, this.resource, true)
this.Request.onreadystatechange := ObjBindMethod(this, "onReadyStateChange")
}
for headerName, headerValue in this.headers
{
this.setHeader(headerName, headerValue)
}
this.defaultHeaders := {}
this.defaultHeaders["User-Agent"] := "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36 u01-05"
this.defaultHeaders["Referer"] := this.resource
this.defaultHeaders["Content-Type"] := "application/x-www-form-urlencoded"
this.defaultHeaders["Pragma"] := "no-cache"
this.defaultHeaders["Cache-Control"] := "no-cache, no-store"
this.defaultHeaders["If-Modified-Since"] := "Sat, 1 Jan 2000 00:00:00 GMT"
return this
}
onReadyStateChange()
{
if (this.getReadyState() != 4)
{
return
}
this.isSend := 1
Func(this.callback).Bind(this).call()
}
getReadyState()
{
return this.Request.readyState
}
send()
{
for headerName, headerValue in this.applyHeaedrs
{
this.Request.SetRequestHeader(headerName, headerValue)
}
this.Request.Send(this.body)
if (!this.callback)
{
this.isSend := 1
}
return this
}
setHeader(headerName, headerValue)
{
if (headerName && headerValue)
{
this.applyHeaedrs[headerName] := headerValue
}
return this
}
getHeader(headerName)
{
return this.applyHeaedrs[headerName]
}
getApplyHeaders()
{
return this.applyHeaedrs
}
getDefaultHeader(headerName)
{
return this.defaultHeaders[headerName]
}
getAllDefaultHeaders()
{
return this.defaultHeaders
}
setDefaultHeader(headerName, headerValue)
{
this.defaultHeaders[headerName] := headerValue
return this
}
applyDefaultHeaders(headers := "")
{
if (!headers)
{
for headerName, headerValue in this.defaultHeaders
{
this.setHeader(headerName, headerValue)
}
}
else
{
for k, headerName in headers
{
defaultHeaderValue := this.defaultHeaders[headerName]
if (defaultHeaderValue)
{
this.setHeader(headerName, defaultHeader)
}
}
}
return this
}
json()
{
return JSON.Parse(this.text())
}
text()
{
return (this.isSend ? this.Request.ResponseText : "")
}
status()
{
return this.Request.Status
}
statusText()
{
return this.Request.StatusText
}
GetAllResponseHeaders()
{
headers := {}
if (!this.isSend)
{
return headers
}
for i, v in strSplit(this.Request.GetAllResponseHeaders(), "`r`n")
{
if (!v)
{
continue
}
if (RegExMatch(v, "UO)^(?<name>.*):\s+(?<params>.*)$", header))
{
headerParams := StrReplace(header.params, """", "\""")
headerParams := StrSplit(headerParams, "; ")
paramsParsed := {}
isValues := false
for i, param in headerParams
{
params := StrSplit(param, "=")
if (params[2])
{
isValues := true
}
paramsParsed[params[1]] := (params[2] ? params[2] : true)
}
headers[header.name] := (isValues ? paramsParsed : headerParams[1])
}
}
return headers
}
}
Я использую его так:
init := {}
init.method := "GET"
init.headers := {"Content-Type": "application/json"}
init.body := {"test": 1}
response := new Fetch("http://localhost:3000/ahk", init, "ready")
response.setHeader("User-Agent", " ")
response.send()
return
ready(res)
{
MsgBox, % res.text()
}
UPD: Если указать любой текст в User-Agent, то он применится. Но почему прокатывает пробел для "WinHttp.WinHttpRequest.5.1"?
UPD:
Для "Msxml2.XMLHTTP" не применяется "Referer".
Запрос с "WinHttp.WinHttpRequest.5.1":
init := {}
init.method := "POST"
init.body := {"test": 1}
response := new Fetch("http://localhost:3000/ahk", init)
response.applyDefaultHeaders().setHeader("User-Agent", "AutoHotKey").setHeader("Content-Type", "application/json")
response.send()
return
::1 - - [07/May/2021:01:57:04 +0000] "GET /ahk HTTP/1.1" 200 326 "http://localhost:3000/ahk" "AutoHotKey"
Запрос с "Msxml2.XMLHTTP":
init := {}
init.method := "POST"
init.body := {"test": 1}
response := new Fetch("http://localhost:3000/ahk", init, "ready")
response.applyDefaultHeaders().setHeader("User-Agent", "AutoHotKey").setHeader("Content-Type", "application/json")
response.send()
return
ready(res)
{
MsgBox, % res.text()
}
::1 - - [07/May/2021:01:53:57 +0000] "GET /ahk HTTP/1.1" 200 355 "-" "AutoHotKey"