通过Django All-auth上的AJAX发布请求登录

时间:2016-12-30 18:36:40

标签: ajax django django-allauth

根据django all-auth的文档,它支持通过AJAX请求登录。当我向" accounts / login /"发出正常的帖子请求时,响应头的内容类型是" text / html"。 但是,当我进行ajax调用时,它是" application / json"。 我无法确定我做错了什么,我尝试在ajax调用中更改contentType和dataType,但它给出了400 Bad request error。

我没有修改任何默认Django all-auth应用程序的URL或视图。

我在这里包含JavaScript代码 -



<script type="text/javascript">
 
var $button = $('#login_button');

    $button.on('click',function(){

      var data = {"csrfmiddlewaretoken" : document.getElementsByName('csrfmiddlewaretoken')[0].value,
       "login": $('#id_login').val(),
       "password": $('#id_password').val(),
       "remember": $('#id_remember').val() };

        var temp = {'X-CSRFToken': document.getElementsByName('csrfmiddlewaretoken'[0].value };

        $.post({
          url : "{% url 'account_login' %}",
          headers: temp,
          type: "POST",
          data : data,
          contentType: "application/x-www-form-urlencoded",
          dataType: "text",
          success : function(data) {
            // console.log(data);
          },

        });

  });



</script>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

我有类似的问题,并且我使用这个解决方案(不是很好的方式,但工作): - 在adapter.py中,您可以看到表单是否无效,状态400和我还更改了数据

def ajax_response(self, request, response, redirect_to=None, form=None):
        data = {}
        status = response.status_code

        if redirect_to:
            status = 200
            data['location'] = redirect_to
        if form:
            if form.is_valid():
                status = 200
            else:
                status = 200
                data['form_errors'] = form._errors
            if hasattr(response, 'render'):
                response.render()
            data = response.content
        return HttpResponse(json.dumps(data),
                            status=status,
                            content_type='application/json')

答案 1 :(得分:0)

它对我有用,请尝试:

{{1}}

答案 2 :(得分:0)

这是我如何将AJAX与原始JavaScript结合使用来登录django-allauth。

django-allauth AJAX响应不包含格式错误,因此我基于Adam Starrh's solution创建了一个基于类的新视图:

from django.http import JsonResponse
from allauth.account.views import LoginView

class AjaxLoginView(LoginView):
    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        if form.is_valid():
            response = self.form_valid(form)
            return JsonResponse({'loggedIn': True})
        else:
            return JsonResponse({'loggedIn': False, 'errors': form.errors})

urls.py中,我为此视图添加了一个路径:

path('login-with-ajax/', AjaxLoginView.as_view(), name='loginWithAjax')

发出AJAX请求的函数执行以下操作:

  1. 使用FormData()创建一个新表单,并添加登录名和密码。
  2. 使用帮助程序方法对表单进行编码。
  3. 使用XMLHttpRequest()通过内容类型"application/x-www-form-urlencoded"发布表单。

这是我使用的方法:

  loginWithAjax(submittedEmail,submittedPassword){
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest()
      let form = new FormData()
      form.set('login', submittedEmail)
      form.set('password', submittedPassword)
      xhr.open('POST', '/accounts/login-with-ajax/')
      xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded") 
      xhr.setRequestHeader("X-CSRFToken", this.getCookie("csrftoken"))
      xhr.onload = () => {
        if (xhr.status === 200) { //received an ajax response from view
          let ajaxResponse = {
            loggedIn: false,
            error: ''
          }
          let viewResponse = JSON.parse(xhr.response)
          ajaxResponse.loggedIn = viewResponse.loggedIn
          if (!ajaxResponse.loggedIn){
            ajaxResponse.error = viewResponse.errors.__all__[0]
          }
          resolve(ajaxResponse)
        } else { //did not receive an ajax response from view
          reject(xhr.status)
        } 
      } 
      xhr.send(this.urlencodeFormData(form))
    }) 
  }

我用the method provided by cuixiping编码形式:

  urlencodeFormData(fd){
    var s = '';
    function encode(s){ return encodeURIComponent(s).replace(/%20/g,'+'); }
    for(var pair of fd.entries()){
        if(typeof pair[1]=='string'){
            s += (s?'&':'') + encode(pair[0])+'='+encode(pair[1]);
        }
    }
    return s;
}

我希望这可以在以后节省一些时间。