-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_js.go
116 lines (95 loc) · 2.34 KB
/
http_js.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// +build js
package ninchat
import (
"errors"
"github.com/gopherjs/gopherjs/js"
)
const userAgentHeader = "X-User-Agent"
var (
xhrType *js.Object
xhrRequestHeaderSupport bool
)
func init() {
xhrType = js.Global.Get("XDomainRequest")
if xhrType == js.Undefined {
xhrType = js.Global.Get("XMLHttpRequest")
if xhrType == js.Undefined {
xhrType = js.Module.Get("require").Invoke("xhr2")
}
xhrRequestHeaderSupport = true
}
}
type httpRequest struct {
Method string
URL string
Header map[string][]string
data *js.Object
}
func newGetRequest(url string, header map[string][]string) (req *httpRequest, err error) {
req = &httpRequest{
Method: "GET",
URL: url,
Header: prepareHeader(header),
}
return
}
func newDataRequest(method, url string, header map[string][]string, data *js.Object) (req *httpRequest, err error) {
req = &httpRequest{
Method: method,
URL: url,
Header: prepareHeader(header),
data: data,
}
return
}
type httpResponse struct {
data *js.Object
err error
}
func getResponseData(req *httpRequest, timeout duration) (*js.Object, error) {
resp := <-getResponseChannel(req, timeout)
return resp.data, resp.err
}
// putResponseChannel makes an XMLHttpRequest, or an XDomainRequest in case of
// IE 8 or 9.
func putResponseToChannel(req *httpRequest, timeout duration, c chan<- httpResponse) {
defer func() {
if err := jsError("XHR", recover()); err != nil {
c <- httpResponse{err: err}
}
}()
xhr := xhrType.New()
xhr.Set("onload", func() {
response := xhr.Get("responseText")
go func() {
c <- httpResponse{data: response}
}()
})
xhr.Set("onprogress", func() {
// https://stackoverflow.com/questions/7037627/long-poll-and-ies-xdomainrequest-object
js.Global.Call("setTimeout", func() {}, 0)
})
xhr.Set("ontimeout", func() {
go func() {
c <- httpResponse{err: errors.New("timeout")}
}()
})
xhr.Set("onerror", func() {
go func() {
c <- httpResponse{err: errors.New("error")}
}()
})
xhr.Call("open", req.Method, req.URL)
xhr.Set("timeout", timeout)
if xhrRequestHeaderSupport {
for k, vv := range req.Header {
for _, v := range vv {
xhr.Call("setRequestHeader", k, v)
}
}
}
js.Global.Call("setTimeout", func() {
// http://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/
xhr.Call("send", req.data)
}, 0)
}