DELETE request using fetch doesn't work in Safari, but works in Chrome

I want to send DELETE request from frontend (React) to backend (Django REST Framework) but it fails with very little info. It works ok in Chrome but fails in Safari. Also it works ok with GET and POST requests, the only thing is that POST requests works only on second attempt (only in Safari, again).

I've tried different CORS configurations but no luck.

Django CORS configuration:

    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ],
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
}

CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
    'localhost:3000',
    'http://localhost:3000',
)

CORS_TRUSTED_ORIGINS = (
    'localhost:3000',
    'http://localhost:3000',
    '*'
)

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = (
    '*',
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'access-control-allow-credentials',
    'access-control-allow-headers',
    'access-control-allow-methods',
    'access-control-allow-origin',
)

Frontend code:

fetch('http://localhost:8000/api-v1/projects/'.concat(this.props.projectId),
        {
            method: 'DELETE',
            mode: 'cors',
            credentials: 'same-origin',
            body: {},
            redirect: 'follow',
            referrer: 'no-referrer',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'Access-Control-Allow-Headers': '*, Origin, X-Requested-With, Content-Type, Accept',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS',
                'Access-Control-Allow-Credentials': true,
                'Authorization': 'Basic ' + btoa('admin:pass'),
            },}).catch( e => console.error(e));

Django logs shows that DELETE request received and the response code is 301. Safari shows this in the console:

[Error] The network connection was lost.
[Error] Fetch API cannot load http://localhost:8000/api-v1/projects/54/ due to access control checks.
[Error] Failed to load resource: The network connection was lost. 
[Error] TypeError: The network connection was lost.
    promiseReactionJob

1 answer

  • answered 2019-06-25 01:09 gosen

    Trailing slash. Freaking trailing slash at the end of the URL. I've spent 5 hours on troubleshooting but the solution was to add one symbol at the end of the URL :)