8
8
// service.
9
9
var urlParsingNode = window . document . createElement ( 'a' ) ;
10
10
var originUrl = urlResolve ( window . location . href ) ;
11
- var baseUrl ;
11
+ var baseUrlParsingNode ;
12
12
13
13
14
14
/**
@@ -44,16 +44,16 @@ var baseUrl;
44
44
* @description Normalizes and parses a URL.
45
45
* @returns {object } Returns the normalized URL as a dictionary.
46
46
*
47
- * | member name | Description |
48
- * |---------------|----------------|
47
+ * | member name | Description |
48
+ * |---------------|------------------------------------------------------------------------ |
49
49
* | href | A normalized version of the provided URL if it was not an absolute URL |
50
- * | protocol | The protocol including the trailing colon |
50
+ * | protocol | The protocol without the trailing colon |
51
51
* | host | The host and port (if the port is non-default) of the normalizedUrl |
52
52
* | search | The search params, minus the question mark |
53
- * | hash | The hash string, minus the hash symbol
54
- * | hostname | The hostname
55
- * | port | The port, without ":"
56
- * | pathname | The pathname, beginning with "/"
53
+ * | hash | The hash string, minus the hash symbol |
54
+ * | hostname | The hostname |
55
+ * | port | The port, without ":" |
56
+ * | pathname | The pathname, beginning with "/" |
57
57
*
58
58
*/
59
59
function urlResolve ( url ) {
@@ -68,19 +68,7 @@ function urlResolve(url) {
68
68
69
69
urlParsingNode . setAttribute ( 'href' , href ) ;
70
70
71
- // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
72
- return {
73
- href : urlParsingNode . href ,
74
- protocol : urlParsingNode . protocol ? urlParsingNode . protocol . replace ( / : $ / , '' ) : '' ,
75
- host : urlParsingNode . host ,
76
- search : urlParsingNode . search ? urlParsingNode . search . replace ( / ^ \? / , '' ) : '' ,
77
- hash : urlParsingNode . hash ? urlParsingNode . hash . replace ( / ^ # / , '' ) : '' ,
78
- hostname : urlParsingNode . hostname ,
79
- port : urlParsingNode . port ,
80
- pathname : ( urlParsingNode . pathname . charAt ( 0 ) === '/' )
81
- ? urlParsingNode . pathname
82
- : '/' + urlParsingNode . pathname
83
- } ;
71
+ return anchorElementToObject ( urlParsingNode ) ;
84
72
}
85
73
86
74
/**
@@ -92,12 +80,11 @@ function urlResolve(url) {
92
80
*/
93
81
function urlIsSameOrigin ( requestUrl ) {
94
82
var parsed = ( isString ( requestUrl ) ) ? urlResolve ( requestUrl ) : requestUrl ;
95
- return ( parsed . protocol === originUrl . protocol &&
96
- parsed . host === originUrl . host ) ;
83
+ return urlsAreSameOrigin ( parsed , originUrl ) ;
97
84
}
98
85
99
86
/**
100
- * Parse a request URL and determine whether it is same-origin as the document base URL.
87
+ * Parse a request URL and determine whether it is same-origin as the current document base URL.
101
88
*
102
89
* Note: The base URL is usually the same the document location (`location.href`) but can
103
90
* overriden by using the `<base>` tag.
@@ -107,10 +94,55 @@ function urlIsSameOrigin(requestUrl) {
107
94
* @returns {boolean } Whether the URL is same-origin as the document base URL.
108
95
*/
109
96
function urlIsSameOriginAsBaseUrl ( requestUrl ) {
110
- if ( ! baseUrl ) {
111
- baseUrl = urlResolve ( '.' ) ;
97
+ if ( ! baseUrlParsingNode ) {
98
+ baseUrlParsingNode = window . document . createElement ( 'a' ) ;
99
+ baseUrlParsingNode . href = '.' ;
100
+
101
+ if ( msie ) {
102
+ // Work-around for IE bug described in Implementation Notes. The fix in urlResolve() is not
103
+ // suitable here because we need to track changes to the base URL.
104
+ baseUrlParsingNode = baseUrlParsingNode . cloneNode ( false ) ;
105
+ }
112
106
}
113
107
var parsed = ( isString ( requestUrl ) ) ? urlResolve ( requestUrl ) : requestUrl ;
114
- return ( parsed . protocol === baseUrl . protocol &&
115
- parsed . host === baseUrl . host ) ;
108
+ return urlsAreSameOrigin ( parsed , anchorElementToObject ( baseUrlParsingNode ) ) ;
109
+ }
110
+
111
+ /**
112
+ * Determines if two URLs share the same origin.
113
+ *
114
+ * @param {object } url1 First URL to compare. Must be a normalized URL in the form of a
115
+ * dictionary object returned by `urlResolve()`.
116
+ * @param {object } url2 Second URL to compare. Must be a normalized URL in the form of a
117
+ * dictionary object returned by `urlResolve()`.
118
+ * @return {boolean } True if both URLs have the same origin, and false otherwise.
119
+ */
120
+ function urlsAreSameOrigin ( url1 , url2 ) {
121
+ // IE sometimes includes a port in the 'host' property, even if it is the default 80 port so
122
+ // we check hostname and port separately.
123
+ return url1 . protocol === url2 . protocol &&
124
+ url1 . hostname === url2 . hostname &&
125
+ url1 . port === url2 . port ;
126
+ }
127
+
128
+ /**
129
+ * Converts properties in the given anchor element into a dictionary object as described in the
130
+ * documentation for `urlResolve()`.
131
+ * @param {HTMLAnchorElement } elem
132
+ * @returns {object }
133
+ */
134
+ function anchorElementToObject ( elem ) {
135
+ // elem provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
136
+ return {
137
+ href : elem . href ,
138
+ protocol : elem . protocol ? elem . protocol . replace ( / : $ / , '' ) : '' ,
139
+ host : elem . host ,
140
+ search : elem . search ? elem . search . replace ( / ^ \? / , '' ) : '' ,
141
+ hash : elem . hash ? elem . hash . replace ( / ^ # / , '' ) : '' ,
142
+ hostname : elem . hostname ,
143
+ port : elem . port ,
144
+ pathname : ( elem . pathname . charAt ( 0 ) === '/' )
145
+ ? elem . pathname
146
+ : '/' + elem . pathname
147
+ } ;
116
148
}
0 commit comments