axios
axios copied to clipboard
AbortController Signal not cancelling requests with CORS
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 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:
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.
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.