Skip to content

jQuery.ajax doesn’t send headers when ‘dataType‘ is ‘script’ and ‘crossDomain’ is true #5142

Closed

Description

@Rinzwind

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='/?url=https%3A%2F%2Fcode.jquery.com%2Fjquery-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?

Activity

  1. mgol commented on Nov 18, 2022

    @mgol
    Member

    Thanks for the report. The script transport has two modes - using a script tag with src or fetching the contents and inserting an inline script (via jQuery.globalEval). The second one requires CORS so the first one is preferred when cross domain. Here are the current conditions:
    https://github.com/jquery/jquery/blob/3.6.1/src/ajax/script.js#L47
    The code on main (future jQuery 4.0) is a bit more involved:

    function canUseScriptTag( s ) {
    // A script tag can only be used for async, cross domain or forced-by-attrs requests.
    // Sync requests remain handled differently to preserve strict script ordering.
    return s.crossDomain || s.scriptAttrs ||
    // When dealing with JSONP (`s.dataTypes` include "json" then)
    // don't use a script tag so that error responses still may have
    // `responseJSON` set. Continue using a script tag for JSONP requests that:
    // * are cross-domain as AJAX requests won't work without a CORS setup
    // * have `scriptAttrs` set as that's a script-only functionality
    // Note that this means JSONP requests violate strict CSP script-src settings.
    // A proper solution is to migrate from using JSONP to a CORS setup.
    ( s.async && jQuery.inArray( "json", s.dataTypes ) < 0 );
    }

    We should investigate adding headers to the list.

    I wonder if this would be a breaking change for 3.x? We'll discuss this at the team's meeting.

  2. added
    Discuss in MeetingReserved for Issues and PRs that anyone would like to discuss in the weekly meeting.
    on Nov 18, 2022
  3. removed
    Discuss in MeetingReserved for Issues and PRs that anyone would like to discuss in the weekly meeting.
    on Nov 21, 2022
  4. added this to the 4.0.0 milestone on Nov 21, 2022
  5. self-assigned this
    on Jan 12, 2023
  6. added 2 commits that reference this issue on Jan 12, 2023
    890f0a6
    2f867d9
  7. mgol commented on Jan 12, 2023

    @mgol
    Member

    PR: #5193

  8. added a commit that references this issue on Feb 1, 2023
    6d13644
  9. mgol commented on Feb 1, 2023

    @mgol
    Member

    For jQuery 4.0, this will be fixed via #5193. For jQuery 3.x, you can workaround by setting crossDomain to false, even if the request is cross-domain.

  10. idiamant commented on Jan 23, 2024

    @idiamant

    Trying with jQuery 3.7.1 to use $.ajax with dataType: jsonp (since it's a crossdomain request), and I need to authenticate with some header. I add the headers parameter, and it's not being passed with the request, and therefore my request fails on authentication.

    When I disable crossDomain / jsonp, the request is failing on CORS, but the header IS being sent.

    Why is that? How can I force it to send the headers with the request using jsonp datatype?

  11. mgol commented on Jan 23, 2024

    @mgol
    Member

    @idiamant JSONP is generally meant to be used via script tags where you have no control over special headers. If the server supports cross-domain XHR, it has to have a working CORS setup. In that case, why even use JSONP which is a hacky insecure workaround for infrastructure without CORS?

    This looks to me like a question better suited for Stack Overflow. Otherwise, please submit a new detailed issue with a test case. I don’t think we’re likely to be looking at a jQuery issue here, though.

  12. idiamant commented on Jan 24, 2024

    @idiamant

    @mgol The issue I was facing is building some web interface which queries a 3rd party service for some data.

    Since this is a 3rd party, I don't control it's CORS settings.

    For now I've implemented a backend "proxy" solution, which will perform the query on the backend side, and provide me with results locally to my server's frontend.

    Tried to avoid using a backend solution for this implementation I'm doing, and only use frontend (allowing me a cheaper hosting of the solution, through some static files bucket).

    If you think this is not relevant, then you may ignore this issue.

  13. locked as resolved and limited conversation to collaborators on Sep 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions