axios icon indicating copy to clipboard operation
axios copied to clipboard

AbortController Signal not cancelling requests with CORS

Open patrickluk opened this issue 2 years ago • 1 comments

Describe the bug

I am adding an AbortController signal to axios GET requests. With a simple GET request without modified headers, the backend GET endpoint was able to receive the cancel request.

However when I add custom headers (eg. Authentication and Refresh) to the AxiosRequestConfig, the backend receives an OPTIONS request followed by a GET request, instead of just a GET request. This is becaues of the preflight request (https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request#:~:text=A%20CORS%20preflight%20request%20is,Headers%20%2C%20and%20the%20Origin%20header). AbortController.abort() wasn't able to cancel the GET request in the backend (I am assuming the OPTIONS endpoint gets cancelled, but it has been completed already)

I am using .NET6 backend with cancellationToken

I tried using the deprecated CancelTokenSource, or using the latest 1.x.x release of axios, but the same issue persists.

To Reproduce

// import
import axios from 'axios'

// modify axios config with intercept
axios.interceptors.request.use((config) => {
    config.headers.Authorization = "Bearer xxxxxxx"
    config.headers.Refresh = "xxxxxxx"
}

// call axios and cancel it
let abortController = new AbortController()
axios.get("someurl", { signal: abortController.signal })
setTimeout(() => {
    abortController.abort()
}, 5000)

Code snippet

No response

Expected behavior

Both OPTIONS and GET gets cancelled in backend

Axios Version

0.26.1

Adapter Version

No response

Browser

Chrome

Browser Version

106.0.5249.119

Node.js Version

14.16.1

OS

Windows 10 21H2

Additional Library Versions

React 17.0.2

Additional context/Screenshots

No response

patrickluk avatar Oct 13 '22 20:10 patrickluk

@patrickluk Hey, I checked your report and believe that abort signals are working correctly. I tested the behavior using a server that always replies with a 200 status code and appropriate CORS headers after a delay of 2000 ms. Sample code (includes React client and Node.js/Koa server): https://github.com/ppati000/axios-issue-5121-investigation.

There are two scenarios: 1) abort during the actual GET request and 2) abort during the preflight request.

Scenario 1: Abort During GET Request

This is what Chrome shows when I abort the request after the preflight request has finished: Captura de Pantalla 2022-10-20 a la(s) 14 06 42 The GET request shows as canceled. Moreover, the Node.js close event is triggered on the incoming request on the server, so everything looks correct.

Scenario 2: Abort During Preflight Request

It looks like the preflight request itself cannot be canceled. If you abort the request while the preflight is still running, the GET request is canceled before it is ever sent, but the preflight request keeps running. Captura de Pantalla 2022-10-20 a la(s) 14 06 27 This behavior kind of makes sense because preflight requests are not in control of the application developer. Also, the browser may cache preflight responses. So it might still be useful for the browser to wait for the preflight response, which may be needed in a later request.

Conclusion

The behavior in scenarios 1 and 2 is consistent between the native fetch and Axios, so I don't think we have any client-side problem here. I would advise to double check the backend implementation.

ppati000 avatar Oct 20 '22 13:10 ppati000