Skip to content

Commit de7ae8c

Browse files
btoewsdmethvin
authored andcommitted
Ajax: use anchor tag for parsing urls
Fixes jquerygh-1875 Closes jquerygh-1880 (cherry picked from commit 5a75278e4c5359e07303fc4d8e78a1cf94f6ad65) Conflicts: src/ajax.js
1 parent 9d1d90e commit de7ae8c

File tree

2 files changed

+33
-22
lines changed

2 files changed

+33
-22
lines changed

src/ajax.js

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ define([
1212
var
1313
rhash = /#.*$/,
1414
rts = /([?&])_=[^&]*/,
15-
rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
15+
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
1616
// #7653, #8125, #8152: local protocol detection
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,10 @@ 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,
42+
// Anchor tag for parsing the document origin
43+
originAnchor = document.createElement( "a" );
4544

46-
// Segment location into parts
47-
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
45+
originAnchor.href = location.href;
4846

4947
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
5048
function addToPrefiltersOrTransports( structure ) {
@@ -287,9 +285,9 @@ jQuery.extend({
287285
etag: {},
288286

289287
ajaxSettings: {
290-
url: ajaxLocation,
288+
url: location.href,
291289
type: "GET",
292-
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
290+
isLocal: rlocalProtocol.test( location.protocol ),
293291
global: true,
294292
processData: true,
295293
async: true,
@@ -381,8 +379,7 @@ jQuery.extend({
381379
// Force options to be an object
382380
options = options || {};
383381

384-
var // Cross-domain detection vars
385-
parts,
382+
var
386383
// Loop variable
387384
i,
388385
// URL without anti-cache param
@@ -391,7 +388,8 @@ jQuery.extend({
391388
responseHeadersString,
392389
// timeout handle
393390
timeoutTimer,
394-
391+
// Url cleanup var
392+
urlAnchor,
395393
// To know if global events are to be dispatched
396394
fireGlobals,
397395

@@ -498,24 +496,33 @@ jQuery.extend({
498496
// Add protocol if not provided (prefilters might expect it)
499497
// Handle falsy url in the settings object (#10093: consistency with old signature)
500498
// We also use the url parameter if available
501-
s.url = ( ( url || s.url || ajaxLocation ) + "" )
502-
.replace( rhash, "" )
503-
.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
499+
s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
500+
.replace( rprotocol, location.protocol + "//" );
504501

505502
// Alias method option to type as per ticket #12004
506503
s.type = options.method || options.type || s.method || s.type;
507504

508505
// Extract dataTypes list
509506
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
510507

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

521528
// 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
@@ -296,7 +296,7 @@ module( "ajax", {
296296
}
297297
]);
298298

299-
ajaxTest( "jQuery.ajax() - cross-domain detection", 7, function() {
299+
ajaxTest( "jQuery.ajax() - cross-domain detection", 8, function() {
300300
function request( url, title, crossDomainOrOptions ) {
301301
return jQuery.extend( {
302302
dataType: "jsonp",
@@ -346,6 +346,10 @@ module( "ajax", {
346346
{
347347
crossDomain: true
348348
}
349+
),
350+
request(
351+
" http://otherdomain.com",
352+
"Cross-domain url with leading space is detected as cross-domain"
349353
)
350354
];
351355
});

0 commit comments

Comments
 (0)