axios: Cancellation may not work well with post
Describe the bug
Followed official doc, Use cancelToken to close pending reqeust, the browser side do cancel the request, but the server side did not receive request cancel signal.
But the get method works well as expected.
To Reproduce
Here is my demo code to reproduce the environment.
First start the server, go run main.go. Second run the client, node index.js.
When js client exit, the server not receive signal as expect.
#!/usr/bin/env node
const { default: axios } = require('axios')
console.log('Hello!')
const source = axios.CancelToken.source()
async function main() {
axios
.post('http://127.0.0.1:5978/debug/context', {}, { cancelToken: source.token })
.then((resp) => {
console.log(resp)
})
.catch((e) => {
console.log('errs', e)
})
await new Promise((r) => setTimeout(r, 5000))
console.log('cancel')
source.cancel()
}
main()
Go Server
package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/debug/context", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
handle(ctx)
fmt.Fprint(w, "ok")
}).Methods("POST")
srv := &http.Server{
Handler: router,
Addr: "0.0.0.0:5978",
}
panic(srv.ListenAndServe())
}
func handle(ctx context.Context) {
exit := make(chan struct{})
i := 1
go func() {
loop:
for {
time.Sleep(time.Second * 1)
fmt.Println("handle func running", i)
i++
select {
case <-exit:
fmt.Println("subroutine exit")
break loop
default:
}
}
}()
<-ctx.Done()
fmt.Println("ctx is done")
fmt.Println("kill sub goroutine")
exit <- struct{}{}
}
Expected behavior
when post request is canceld, expect server side recevice signal. For example, goroutine context is Done and release some resource.
Environment
- Axios Version 0.24.0
- Adapter HTTP
- Browser Chrome, Nodejs
- Browser Version Chrome: 96.0.4664.93
- Node.js Version v14.17.6
- OS: Ubuntu 18.04
- Additional Library Versions: NULL
Additional context/Screenshots
Add any other context about the problem here. If applicable, add screenshots to help explain.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 19 (4 by maintainers)
UPDATED
FOUND THE REASON for me: I used proxy server for my React SPA (
http-proxy-middleware
package insetupProxy.js
) and it breaks cancellation behaviour. For production mode and original server everything working as expected.API Proxy (SPA) always handle requests to origin server (cancellation isn’t supported in
http-proxy-middleware
package).@arthurfiorette If you need a demo WebAPI project for C# (.NET 6), I can make a new demo repo.
We will also need to check how it handles via deprecated
axios.CancelToken
?Here is basic NodeJS server (express) with cancellation support:
I’m using NodeJS
v16.15.0
for now on Windows 10 1803 OS. Latest browsers (Chrome and Firefox).I’m upgrading CancelToken to AbortController, but something goes wrong. I use AbortController as a global variable,and set axios defaults like this:
And cancel some requests when user is closing a modal:
After one single abortion, all of the requests can’t be made again, yes all of them. Nothing happens in the F12 network panel. But those request promises are likely resolved directly and returned null, so that I get errors in ‘then’ handler instead of ‘catch’.
Did I use AbortController in a wrong way?
@alienzhangyw
UPDATED
Clone demo project
You can clone the demo repository: react-demo-abort-controller-proxy-issue.
Or create new project
src/setupProxy.js
file with content:/
to/api/test
(for proxy request matching):App.js
:node index.js
:npm run start
Description of the resulting behavior
After you can make some requests, cancel all and reproduce the issue. You will get messages on the server (after dev proxy):
But expected demo server behavior is:
@zhangzhiqiangcs It looks like this is some kind of problem with your backend (proxy/server). You can simply use your network console to make sure that the Axios connection is aborted normally.
node.js server:
client page (./public/index.html):
normal request log:
aborted request log:
According to the Axios docs, Abort Controller support begins with version 0.22.0, so your best bet would be to upgrade
@alienzhangyw I have the same issue but even in local scope. After running some tests on a perfectly working .NET 6 WebAPI Server with request cancellation support, I found out that Axios really doesn’t cancel requests, it just putting the promise into a failed state as @gerryfletch said.
Again, the server is absolutely correct in canceling requests, I checked this in Postman.
Surprisingly, using build-in
fetch(url, { signal })
, the request isn’t cancelled either inGoogle Chrome
or inFirefox
browsers! Promise changed state to failed but the request is fully processed by server without cancellation.