2017-05-09 116 views
0

我有一个使用graphene-django实现的graphql服务器。我可以使用jquery这样进行查询到它:Django在POST请求上返回403错误,提取

function allIngredients() { 
    return 'query{allProducts{edges{node{name}}}}' 
    } 
    var query = allIngredients(); 
    $.ajaxSetup({ 
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' }, 
    }); 
    $.post("/graphql", {query: query}, function(response) { 
    console.log(response); 
    }) 

然而,当我尝试此调用与取,我得到一个403,因为CORS问题。我通过在调用之前添加ajaxSetup ...来解决jQuery中的相同问题。

下面是一个使用获取的呼叫:

fetch('/graphql', { 
     method: "POST", 
     headers: { 
      'Content-Type': 'application/json' 
     }, 
     credentials: 'include', 
     body: JSON.stringify({ 
      csrfmiddlewaretoken: '{{ csrf_token }}', 
      query:`{allProducts{ 
      edges{ 
       node{ 
       id 
       name 
       orderPrice 
       sellPrice 
       } 
      } 
      }`}) 
     } 
    ) 
    .then(function(response) { 
     if (response.status >= 400) { 
      throw new Error("Bad response from server"); 
     } 
     return response.json(); 
    }) 

我尝试添加csrfmiddlewaretoken到身在类似的方式,我在jQuery的例子一样,没有运气。我尝试添加凭据:'包含'为the docs say,再次没有运气。我尝试了凭据:“同源”,并将这些选项以不同的方式组合,再次得到相同的结果。网站对此非常安静,我做错了什么?

回答

0

该解决方案在getCookie()方法中。

fetch("/graphql", { 
     method: "POST", 
     credentials: "same-origin", 
     headers: { 
      "X-CSRFToken": getCookie("csrftoken"), 
      "Accept": "application/json", 
      'Content-Type': 'application/json' 
     }, 
     body:JSON.stringify(query) 
     }) 

当然,该方法必须在同一页上。从Django Docs.

function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie !== '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
      var cookie = jQuery.trim(cookies[i]); 
      // Does this cookie string begin with the name we want? 
      if (cookie.substring(0, name.length + 1) === (name + '=')) { 
       cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
       break; 
      } 
     } 
    } 
    return cookieValue; 
} 
2

采取如果你想使该职位的要求形成不同的域(在情况下,当应用程序的前面是反应或角和后端是在Django),请确保以下附加设置文件:

  1. 更新INSTALLED_APPS使用 'coreHeaders':

    INSTALLED_APPS = [
    'corsheaders',
    ]

  2. 白名单中加入以下内容设置您的前端域再次文件:

    CORS_ORIGIN_WHITELIST =( 的 'localhost:8080', )

现在允许允许任何人发布此帖子请求:

注意:应该在您不需要认证用户在我们的服务器上发布任何内容的情况下使用,例如,当新用户首次注册时

from rest_framework.permissions import AllowAny 

class CreateUser(APIView): 
    permission_classes = (AllowAny,) 
    def post(self, request, format=None): 
     return(Response("hi"))