Skip to content
This repository was archived by the owner on Dec 1, 2023. It is now read-only.

Commit b2fc84c

Browse files
committed
detect cross-origin requests
1 parent 76e012f commit b2fc84c

File tree

4 files changed

+60
-43
lines changed

4 files changed

+60
-43
lines changed

src/http.js

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ var jsonType = {'Content-Type': 'application/json;charset=utf-8'};
99

1010
module.exports = function (Vue) {
1111

12+
var Url = Vue.url;
13+
var originUrl = Url.parse(location.href);
14+
1215
function Http(url, options) {
1316

14-
var self = this, headers, promise;
17+
var self = this, promise;
1518

1619
options = options || {};
1720

@@ -20,21 +23,45 @@ module.exports = function (Vue) {
2023
url = '';
2124
}
2225

23-
headers = _.extend({},
24-
Http.headers.common,
25-
Http.headers[options.method.toLowerCase()]
26+
options = _.extend(true, {url: url},
27+
Http.options, _.options('http', this, options)
2628
);
2729

28-
options = _.extend(true, {url: url, headers: headers},
29-
Http.options, _.options('http', this, options)
30+
if (options.crossOrigin === null) {
31+
options.crossOrigin = crossOrigin(options.url);
32+
}
33+
34+
options.headers = _.extend({},
35+
Http.headers.common,
36+
!options.crossOrigin ? Http.headers.custom : {},
37+
Http.headers[options.method.toLowerCase()],
38+
options.headers
3039
);
3140

3241
if (_.isPlainObject(options.data) && /^(get|jsonp)$/i.test(options.method)) {
3342
_.extend(options.params, options.data);
3443
delete options.data;
3544
}
3645

37-
promise = (options.method.toLowerCase() == 'jsonp' ? jsonp : xhr).call(this, this.$url || Vue.url, options);
46+
if (options.emulateHTTP && !option.crossOrigin && /^(put|patch|delete)$/i.test(options.method)) {
47+
options.headers['X-HTTP-Method-Override'] = options.method;
48+
options.method = 'post';
49+
}
50+
51+
if (options.emulateJSON && _.isPlainObject(options.data)) {
52+
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
53+
options.data = Url.params(options.data);
54+
}
55+
56+
if (_.isObject(options.data) && /FormData/i.test(options.data.toString())) {
57+
delete options.headers['Content-Type'];
58+
}
59+
60+
if (_.isPlainObject(options.data)) {
61+
options.data = JSON.stringify(options.data);
62+
}
63+
64+
promise = (options.method.toLowerCase() == 'jsonp' ? jsonp : xhr).call(this, this.$url || Url, options);
3865

3966
promise.then(transformResponse, transformResponse);
4067

@@ -88,12 +115,20 @@ module.exports = function (Vue) {
88115

89116
}
90117

118+
function crossOrigin(url) {
119+
120+
var requestUrl = Url.parse(url);
121+
122+
return (requestUrl.protocol !== originUrl.protocol || requestUrl.host !== originUrl.host);
123+
}
124+
91125
Http.options = {
92126
method: 'get',
93127
params: {},
94128
data: '',
95129
jsonp: 'callback',
96130
beforeSend: null,
131+
crossOrigin: null,
97132
emulateHTTP: false,
98133
emulateJSON: false
99134
};
@@ -103,10 +138,8 @@ module.exports = function (Vue) {
103138
post: jsonType,
104139
patch: jsonType,
105140
delete: jsonType,
106-
common: {
107-
'Accept': 'application/json, text/plain, */*',
108-
'X-Requested-With': 'XMLHttpRequest'
109-
}
141+
common: {'Accept': 'application/json, text/plain, */*'},
142+
custom: {'X-Requested-With': 'XMLHttpRequest'}
110143
};
111144

112145
['get', 'put', 'post', 'patch', 'delete', 'jsonp'].forEach(function (method) {

src/lib/xhr.js

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,6 @@ module.exports = function (url, options) {
1313
options.beforeSend.call(this, request, options);
1414
}
1515

16-
if (options.emulateHTTP && /^(put|patch|delete)$/i.test(options.method)) {
17-
options.headers['X-HTTP-Method-Override'] = options.method;
18-
options.method = 'post';
19-
}
20-
21-
if (options.emulateJSON && _.isPlainObject(options.data)) {
22-
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
23-
options.data = url.params(options.data);
24-
}
25-
26-
if (_.isObject(options.data) && /FormData/i.test(options.data.toString())) {
27-
delete options.headers['Content-Type'];
28-
}
29-
30-
if (_.isPlainObject(options.data)) {
31-
options.data = JSON.stringify(options.data);
32-
}
33-
3416
promise = new Promise(function (resolve, reject) {
3517

3618
request.open(options.method, url(options), true);

src/resource.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ module.exports = function (Vue) {
6767

6868
if (_.isFunction (args[0])) {
6969
success = args[0];
70-
} else if (/^(POST|PUT|PATCH)$/i.test(options.method)) {
70+
} else if (/^(post|put|patch)$/i.test(options.method)) {
7171
data = args[0];
7272
} else {
7373
params = args[0];
@@ -101,11 +101,11 @@ module.exports = function (Vue) {
101101

102102
Resource.actions = {
103103

104-
get: {method: 'GET'},
105-
save: {method: 'POST'},
106-
query: {method: 'GET'},
107-
remove: {method: 'DELETE'},
108-
delete: {method: 'DELETE'}
104+
get: {method: 'get'},
105+
save: {method: 'post'},
106+
query: {method: 'get'},
107+
remove: {method: 'delete'},
108+
delete: {method: 'delete'}
109109

110110
};
111111

src/url.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
var _ = require('./lib/util');
6+
var el = document.createElement('a');
67

78
module.exports = function (Vue) {
89

@@ -93,16 +94,17 @@ module.exports = function (Vue) {
9394

9495
Url.parse = function (url) {
9596

96-
var pattern = new RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?"),
97-
matches = url.match(pattern);
97+
el.href = url;
9898

9999
return {
100-
url: url,
101-
scheme: matches[1] || '',
102-
host: matches[2] || '',
103-
path: matches[3] || '',
104-
query: matches[4] || '',
105-
fragment: matches[5] || ''
100+
href: el.href,
101+
protocol: el.protocol ? el.protocol.replace(/:$/, '') : '',
102+
port: el.port,
103+
host: el.host,
104+
hostname: el.hostname,
105+
pathname: el.pathname.charAt(0) === '/' ? el.pathname : '/' + el.pathname,
106+
search: el.search ? el.search.replace(/^\?/, '') : '',
107+
hash: el.hash ? el.hash.replace(/^#/, '') : ''
106108
};
107109
};
108110

0 commit comments

Comments
 (0)