Получение ошибки разбора JSON при использовании FETCH, но не при использовании PostMan

I have set up an API endpoint using Django and django-rest-framework to submit a form using a POST request. When sending the request with PostMan, the backend works fine and adds the data to the DB. However, when I use fetch the backend returns {"detail":"JSON parse error - Expecting value: line 1 column 1 (char 0)"}. The frontend is a react webpack setup.

Этот код я использую для выполнения запроса:

    let csrftoken = getCookie('csrftoken')

    const jsonString = JSON.stringify(data,null, '    ')
    console.log(jsonString)

    const response = await fetch(baseURL + 'jobs/',{
        method: 'POST',
        mode: 'same-origin',
        cache: 'no-cache',
        credentials: 'same-origin',
        headers: {
            'Content-Type': 'application/json',
            'Accept': '*/*',
            'X-CSRFToken': csrftoken,
            'Accept-Encoding': 'gzip, deflate, br'
        },
        body: jsonString
        });
    return response.json()
}

Здесь выводится jsonString:

{
    "data": "asdf",
    "mode": "text",
    "node": "sdaf",
    "species": "asdf",
    "model_type": "proto",
    "dry_run": false,
    "single_fam_mode": false,
    "mail_address": ""
}

Я также использовал wireshark для захвата запроса PostMan и запроса на выборку. Вот запрос PostMan с успешным ответом:

[1 bytes missing in capture file].POST /api/jobs/ HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.28.3
Accept: */*
Postman-Token: 8c4b0ff0-5430-4420-8785-e965a808db5c
Host: localhost:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 184

{
    "data": "asdsadad",
    "mode": "text",
    "node": "katten",
    "model_type": "both",
    "dry_run": false,
    "single_fam_mode": false,
    "mail_address": "test@teast1.no"
}HTTP/1.1 201 Created
Date: Tue, 31 Aug 2021 09:10:32 GMT
Server: WSGIServer/0.2 CPython/3.8.5
Content-Type: application/json
Vary: Accept, Origin, Cookie
Allow: GET, POST, OPTIONS
X-Frame-Options: DENY
Content-Length: 271
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin

{"id": "4c6baad3-be1a-4463-8c06-edec51443565", "initiated": "2021-08-31T09:10:32.850533Z", "data": "asdsadad", "mode": "text", "species": "job@09:10:32", "node": "katten", "model_type": "both", "dry_run": false, "single_fam_mode": false, "mail_address": "test@teast1.no"}

Вот запрос на выборку с ответом 400:

POST /api/jobs/ HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: nb-NO,nb;q=0.9,no-NO;q=0.8,no;q=0.6,nn-NO;q=0.5,nn;q=0.4,en-US;q=0.3,en;q=0.1
Accept-Encoding: gzip, deflate
Referer: http://localhost:8000/
Content-Type: application/json
X-CSRFToken: Qv2chVzt4hiDZbe7jYDtUiP7o3IuXzVHnUUc03PYZI8FWKrOCC655rdoaThgQb1B
Origin: http://localhost:8000
Content-Length: 164
DNT: 1
Connection: keep-alive
Cookie: csrftoken=Qv2chVzt4hiDZbe7jYDtUiP7o3IuXzVHnUUc03PYZI8FWKrOCC655rdoaThgQb1B; sessionid=eqh9wotdlhh43ubszv7ievd03fnhh0fl
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: same-origin
Sec-Fetch-Site: same-origin

{
    "data": "sadf",
    "mode": "text",
    "node": "asdf",
    "species": "asdf",
    "model_type": "proto",
    "dry_run": false,
    "single_fam_mode": false,
    "mail_address": ""
}HTTP/1.1 400 Bad Request
Date: Tue, 31 Aug 2021 10:03:05 GMT
Server: WSGIServer/0.2 CPython/3.8.5
Content-Type: application/json
Vary: Accept, Origin, Cookie
Allow: GET, OPTIONS, POST
X-Frame-Options: DENY
Content-Length: 73
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin

{"detail":"JSON parse error - Expecting value: line 1 column 1 (char 0)"}

Я не включил код бэкенда, так как предполагаю, что он работает нормально, поскольку запрос postman проходит успешно.

Может ли кто-нибудь сказать мне, в чем проблема с моим запросом fetch?

Как было выделено выше, попробуйте urllib3, ваш код может выглядеть следующим образом:

import urllib3
import json

def get_response():
    data = {
        "data": "asdf",
        "mode": "text",
        "node": "sdaf",
        "species": "asdf",
        "model_type": "proto",
        "dry_run": False,
        "single_fam_mode": False,
        "mail_address": ""
        }

    try:

        encoded_data = json.dumps(data).encode('utf-8')
        http = urllib3.PoolManager()

        response = http.request(
            'POST',
            baseURL + 'jobs/',
            body=encoded_data,
            headers={
                'Content-Type': 'application/json',
                'Accept': '*/*',
                'X-CSRFToken': csrftoken,
                'Accept-Encoding': 'gzip, deflate, br'
            }
        )
        return json.loads(response.data.decode('utf-8'))

    except:
        #Handle your error
        pass

Я могу предложить вам попробовать передать body без стрингера. Я менее знаком с react.js, но в обычных запросах ajax - json передается как есть, без структурирования. Т.е.:

const response = await fetch(baseURL + 'jobs/',{
    ...
    body: data
    });

Решено! На самом деле это была проблема с firefox (v. 91.0.2 Mac OS X). Как только я перешел на safari или браузер разработчика firefox, все заработало. Хотя не уверен, в чем на самом деле была проблема.

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