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
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.
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.
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
Line 18 in 250a199
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')
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.
[]
How to set a custom header?
I tried with headers
and beforeSend
but both show the same error:
<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>
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.
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+'');
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.
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.
Bug Reports:
With [prevAll] and then with [wrapAll], the order of the nodes in the dom changes
<!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>
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.
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?
edge (if you click by page after reload):
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):
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
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
.
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:
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>
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?