Skip to content

Commit b091fdb

Browse files
btoewsdmethvin
authored andcommitted
Ajax: use anchor tag for parsing urls
Fixes jquerygh-1875 Closes jquerygh-1880
1 parent cfe468f commit b091fdb

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

src/ajax.js

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ var
1717
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
1818
rnoContent = /^(?:GET|HEAD)$/,
1919
rprotocol = /^\/\//,
20-
rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
2120

2221
/* Prefilters
2322
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
@@ -40,11 +39,9 @@ var
4039
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
4140
allTypes = "*/".concat( "*" ),
4241

43-
// Document location
44-
ajaxLocation = location.href,
45-
46-
// Segment location into parts
47-
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
42+
// Anchor tag for parsing the document origin
43+
originAnchor = document.createElement( "a" );
44+
originAnchor.href = location.href;
4845

4946
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
5047
function addToPrefiltersOrTransports( structure ) {
@@ -288,9 +285,9 @@ jQuery.extend({
288285
etag: {},
289286

290287
ajaxSettings: {
291-
url: ajaxLocation,
288+
url: location.href,
292289
type: "GET",
293-
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
290+
isLocal: rlocalProtocol.test( location.protocol ),
294291
global: true,
295292
processData: true,
296293
async: true,
@@ -390,8 +387,8 @@ jQuery.extend({
390387
responseHeaders,
391388
// timeout handle
392389
timeoutTimer,
393-
// Cross-domain detection vars
394-
parts,
390+
// Url cleanup var
391+
urlAnchor,
395392
// To know if global events are to be dispatched
396393
fireGlobals,
397394
// Loop variable
@@ -496,23 +493,33 @@ jQuery.extend({
496493
// Add protocol if not provided (prefilters might expect it)
497494
// Handle falsy url in the settings object (#10093: consistency with old signature)
498495
// We also use the url parameter if available
499-
s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
500-
.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
496+
s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
497+
.replace( rprotocol, location.protocol + "//" );
501498

502499
// Alias method option to type as per ticket #12004
503500
s.type = options.method || options.type || s.method || s.type;
504501

505502
// Extract dataTypes list
506503
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
507504

508-
// A cross-domain request is in order when we have a protocol:host:port mismatch
505+
// A cross-domain request is in order when the origin doesn't match the current origin.
509506
if ( s.crossDomain == null ) {
510-
parts = rurl.exec( s.url.toLowerCase() );
511-
s.crossDomain = !!( parts &&
512-
( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
513-
( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
514-
( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
515-
);
507+
urlAnchor = document.createElement( "a" );
508+
509+
// Support: IE8-11+
510+
// IE throws exception if url is malformed, e.g. http://example.com:80x/
511+
try {
512+
urlAnchor.href = s.url;
513+
// Support: IE8-11+
514+
// Anchor's host property isn't correctly set when s.url is relative
515+
urlAnchor.href = urlAnchor.href;
516+
s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
517+
urlAnchor.protocol + "//" + urlAnchor.host;
518+
} catch ( e ) {
519+
// If there is an error parsing the URL, assume it is crossDomain,
520+
// it can be rejected by the transport if it is invalid
521+
s.crossDomain = true;
522+
}
516523
}
517524

518525
// Convert data if not already a string

test/unit/ajax.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ module( "ajax", {
301301
}
302302
]);
303303

304-
ajaxTest( "jQuery.ajax() - cross-domain detection", 7, function() {
304+
ajaxTest( "jQuery.ajax() - cross-domain detection", 8, function() {
305305
function request( url, title, crossDomainOrOptions ) {
306306
return jQuery.extend( {
307307
dataType: "jsonp",
@@ -351,6 +351,10 @@ module( "ajax", {
351351
{
352352
crossDomain: true
353353
}
354+
),
355+
request(
356+
" http://otherdomain.com",
357+
"Cross-domain url with leading space is detected as cross-domain"
354358
)
355359
];
356360
});

0 commit comments

Comments
 (0)