Trying to send basic string to Django Backend via POST request using axios but no data is sent

I've been trying a basic string to Django backend from frontend using axios.post call.

Connection is ensured and backend side detects the request but the data is empty.

Frontend side:

const axios = Axios.create({
     baseURL: API_URL,
     headers: {
       'Content-Type': 'application/json',
     },
});

export class MessageService {
static async sendMessage(message: string): Promise<any> {
    try {
    const data = {question: message}
    // Uncomment the line below to use the actual API call
    const response = await axios.post('/chatbot/rest_handler', data);

    return response;
    } catch (error) {
    console.error('Error sending message:', error);
    throw error;
    }
}

Backend side:

@csrf_exempt
def rest_handler(request):
    print("REQUEST IS SENT FROM FRONTEND")
    req_data = request.body
    q_info = req_data.decode("utf-8")
    print("QUESTION:"+ q_info)
    return JsonResponse(request)

But in the output screen, I see an empty string:

[09/Jun/2025 10:49:33] "OPTIONS /chatbot/rest_handler HTTP/1.1" 200 2
REQUEST IS SENT FROM FRONTEND
QUESTION:

request.body really is empty on the request your view is receiving—but that request is not the POST you think it is.
What you’re printing is the browser’s CORS pre-flight:

[09/Jun/2025 10:49:33] "OPTIONS /chatbot/rest_handler HTTP/1.1" 200 2 

Why you only see an empty body

  1. Pre-flight = OPTIONS
    When your React/Vite/Next/etc. frontend is served from a different origin/port than Django, the browser first sends an OPTIONS request to check whether the real request is allowed. A pre-flight never carries a body, so request.body is b''.

  2. The real POST never runs
    Because Django doesn’t answer the pre-flight with the required CORS headers, the browser never follows up with the POST. Your view therefore never sees the JSON payload.

Fixing it

Add proper CORS handling

The simplest and most robust way is to install django-cors-headers:

pip install django-cors-headers 
# settings.py
INSTALLED_APPS = [
    ...
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # must be high in the list
    ...
]

CORS_ALLOWED_ORIGINS = [
    "http://localhost:5173",  # your Vite/React dev server
    "https://your-frontend.example",
]
# If you want to allow credentials (cookies) add:
# CORS_ALLOW_CREDENTIALS = True

The middleware automatically:

  • Responds to pre-flight OPTIONS with Access-Control-Allow headers

  • Lets the browser send the real POST that contains your JSON body.

Only handle the POST in your view

@csrf_exempt
def rest_handler(request):
    if request.method == "OPTIONS":
        return HttpResponse(status=200)
    elif request.method == "POST":
        print("REQUEST IS SENT FROM FRONTEND")
        req_data = request.body
        q_info = req_data.decode("utf-8")
        print("QUESTION:"+ q_info)
        return JsonResponse(request)

So, in this case you are just responding with 200 when you get the OPTIONS respond and then try to catch POST respond, which should contain your data.

Вернуться на верх