POST 方法返回方法不允许 405

huangapple go评论74阅读模式
英文:

NGINX Django DRF Vue.js POST method returns Method Get not allowed 405

问题

I am building an ecommerce site. Everything works well, except the forms. When I try to post something, it returns me 405 method get not allowed. Why is it giving GET error when I am trying to do POST? It works on some forms, like for example checkout. But when I try to use contact form and press send axios.post('/api/v1/contacto/', data) it gets me this error 405. BTW, when I am using this e-commerce running it on my local machine, it works well.

Here is my sites-available:

upstream ecologic_app_server {
    server unix:/webapps/ecologic/backend/venv/run/gunicorn.sock fail_timeout=0;
}

server {
    listen 8000;
    listen [::]:8000;
    server_name myiphere;

    client_max_body_size 40M;

    location / {
        root /webapps/ecologic/frontend;
        try_files $uri /index.html;
        index index.html index.htm;
    }

    location /static/ {
        root /webapps/ecologic/backend;
    }

    location /media/ {
        root /webapps/ecologic/backend;
    }

    location /api/v1/ {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Host $http_host;
        proxy_pass http://ecologic_app_server/api/v1/;
        proxy_ssl_session_reuse off;
        proxy_redirect off;
    }

    location /admin/ {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://ecologic_app_server/admin/;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
}

This is my urls.py:

from django.urls import path, include
from . import views

urlpatterns = [
    path('contacto/', views.contact_form_post),
    path('reclamo/', views.complaints_form_post),
]

Here is my code for contact form:

@api_view(['POST'])
def contact_form_post(request):
    if request.method == "POST":
        serializer = ContactForm(data=request.data)
        if serializer.is_valid():

            first_name = serializer.validated_data['first_name']
            last_name = serializer.validated_data['last_name']
            phone = serializer.validated_data['phone']
            email = serializer.validated_data['email']
            subject = serializer.validated_data['subject']
            message = serializer.validated_data['message']

            print(first_name, last_name, phone, email, subject, message)

            context = {
                'first_name': first_name,
                'last_name': last_name,
                'phone': phone,
                'email': email,
                'subject': subject,
                'message': message
            }

            html = render_to_string('emails/contact.html', context)
            text = render_to_string('emails/contact.txt', context)

            recipient = MainSettings.objects.first().contact_email

            send_mail(
                subject,
                message=text,
                html_message=html,
                from_email=settings.DEFAULT_FROM_EMAIL,
                recipient_list=[recipient],
                fail_silently=False,
            )
            serializer.save()

        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

What could be the problem? Thank you.

英文:

I am building an ecommerce site. Everything works well, except the forms. When I try to post something, it returns me 405 method get not allowed. Why is it giving GET error when I am trying to do POST? It works on some forms, like for example checkout. But when I try to use contact form and press send axios.post('/api/v1/contacto/', data) it gets me this error 405. BTW, when I am using this e-commerce running it on my local machine, it works well.

Here is my sites-available:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

upstream ecologic_app_server {
server unix:/webapps/ecologic/backend/venv/run/gunicorn.sock fail_timeout=0;
}
server {
listen 8000;
listen [::]:8000;
server_name myiphere;
client_max_body_size 40M;
location / {
root /webapps/ecologic/frontend;
try_files $uri /index.html;
index index.html index.htm;
}
location /static/ {
root /webapps/ecologic/backend;
}
location /media/ {
root /webapps/ecologic/backend;
}
location /api/v1/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Host $http_host;
proxy_pass http://ecologic_app_server/api/v1/;
proxy_ssl_session_reuse off;
proxy_redirect off;
}
location /admin/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://ecologic_app_server/admin/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}

<!-- end snippet -->

This is my urls.py:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

from django.urls import path, include
from . import views
urlpatterns = [
path(&#39;contacto/&#39;, views.contact_form_post),
path(&#39;reclamo/&#39;, views.complaints_form_post),
]

<!-- end snippet -->

Here is my code for contact form:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

@api_view([&#39;POST&#39;])
def contact_form_post(request):
if request.method == &quot;POST&quot;:
serializer = ContactForm(data=request.data)
if serializer.is_valid():
first_name = serializer.validated_data[&#39;first_name&#39;]
last_name = serializer.validated_data[&#39;last_name&#39;]
phone = serializer.validated_data[&#39;phone&#39;]
email = serializer.validated_data[&#39;email&#39;]
subject = serializer.validated_data[&#39;subject&#39;]
message = serializer.validated_data[&#39;message&#39;]
print(first_name, last_name, phone, email, subject, message)
context = {
&#39;first_name&#39;: first_name,
&#39;last_name&#39;: last_name,
&#39;phone&#39;: phone,
&#39;email&#39;: email,
&#39;subject&#39;: subject,
&#39;message&#39;: message
}
html = render_to_string(&#39;emails/contact.html&#39;, context)
text = render_to_string(&#39;emails/contact.txt&#39;, context)
recipient = MainSettings.objects.first().contact_email
send_mail(
subject,
message=text,
html_message=html,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[recipient],
fail_silently=False,
# auth_user=None, auth_password=None, connection=None, html_message=None
)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

<!-- end snippet -->

What could be the problem? Thank you.

答案1

得分: 1

这个问题可能是一个Nginx配置问题。

这个问题相关,可能会有所帮助:

https://stackoverflow.com/questions/24415376/post-request-not-allowed-405-not-allowed-nginx-even-with-headers-included

关于它在你本地运行正常,请将你的应用程序Docker化。

英文:

I suppose that its an Nginx config problem.

This question is related and may help:

https://stackoverflow.com/questions/24415376/post-request-not-allowed-405-not-allowed-nginx-even-with-headers-included

Regarding that it works on your local, please Dockerize your app.

答案2

得分: 0

我已找到此问题的解决方案。由于某种原因,即使您无需登录或注册即可发送联系电子邮件,但不允许使用POST方法。我的Django后端应用程序的settings.py设置是正确的,我没有在那里指定任何与身份验证相关的内容。我通过将AllowAny添加到使用POST方法的视图中来解决了这个问题。在您的views.py中首先添加:

from rest_framework.permissions import AllowAny

然后,您添加:

@api_view(['POST'])
@permission_classes([AllowAny])
def contact(request):

所以,我不确定为什么它会以这种方式工作。即使在那之后,我尝试删除它,也可以正常工作,而不需要AllowAny。

英文:

I have found a solution for this case. For some reason, POST methods were not allowed even though you didn't have to log in o register to send a contact email. The settings.py of my Django backend app was good. I didn't specify there anything related to being authenticated. I was able to solve that by adding AllowAny to my views that use POST method. In your views.py first add:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

from rest_framework.permissions import AllowAny

<!-- end snippet -->

Then, you add:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

@api_view([&#39;POST&#39;])
@permission_classes([AllowAny])
def contact(request):

<!-- end snippet -->

So, I am not sure why this is working that way. Even after that, I tried deleting it and it worked well without AllowAny.

huangapple
  • 本文由 发表于 2023年6月1日 01:56:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76376165.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定