Как мне ответить на CanCan :: AccessDenied ответом JJ AJAX? - PullRequest
0 голосов
/ 14 сентября 2018

Я хочу ответить на CanCan::AccessDenied с помощью JSON, если запрос выполняется через AJAX, но он всегда отвечает со статусом 200 и перенаправлением независимо. Я хочу реализовать этот ответ: https://stackoverflow.com/a/10013873/148844. Я не знаю, как он переопределяет статус с 302 на 200, не говоря уже об отсутствии рендеринга JSON. Я также попробовал format.js, но это не сработало.

application_controller.rb
class ApplicationController < ActionController::Base
  include CanCan::ControllerAdditions

  rescue_from CanCan::AccessDenied do |exception|
    flash[:warning] = exception.message
    logger.info exception
    respond_to do |format|
      logger.info "format: " + format.to_s
      format.html do
        if user_signed_in? && current_user.type
          redirect_to "/dashboard"
        else
          redirect_to root_path
        end
      end
      format.json do
        render json: {success: false, message: 'Access Denied: '+exception.message}, status: 401
      end
    end
  end
CoffeeScript
$.post "/topics/order", {'id_order[]': arr}, (data, textStatus, jqXHR) ->
  ...
Gemfile
gem 'cancancan', '~> 1.10'
Console
Started POST "/topics/order" for ::1 at 2018-09-14 14:44:33 -0400
...
You are not authorized to access this page.
format: #<ActionController::MimeResponds::Collector:0x0000000d4b2a28>
Redirected to http://localhost:3000/dashboard
Completed 200 OK in 314ms (ActiveRecord: 28.0ms)

https://github.com/CanCanCommunity/cancancan#4-handle-unauthorized-access

https://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to


Я провел некоторое тестирование и добавил

  format.json { head :forbidden, content_type: 'text/html' }
  format.js   { head :forbidden, content_type: 'text/html' }

К началу respond_to блока, и это работает. При перемещении на нижнюю часть блока это не работает. Rails, кажется, отвечает на самый первый format, который он видит, независимо от формата!

1 Ответ

0 голосов
/ 14 сентября 2018

Я добавил json как dataType к сообщению, и теперь оно работает.

$.post "/topics/order", {'id_order[]': arr}, (data, textStatus, jqXHR) ->
  ...
, 'json'

https://api.jquery.com/jquery.ajax/#jQuery-ajax-settings

dataType (по умолчанию: Intelligent Guess (xml, json, script или html))
Тип: String
Тип данных, ожидаемых от сервера.Если ничего не указано, jQuery попытается вывести его на основе MIME-типа ответа (XML MIME-тип даст XML, в 1.4 JSON выдаст объект JavaScript, в 1.4 скрипт выполнит скрипт, а все остальное будетвозвращается как строка).Доступные типы (и результат, переданный в качестве первого аргумента в ваш обратный вызов успеха):

"json": Оценивает ответ как JSON и возвращает объект JavaScript.Междоменные запросы «json», имеющие заполнитель обратного вызова, например, «callback =», выполняются с использованием JSONP, если запрос не включает в свои параметры jsonp: false.Данные JSON анализируются строго;любой искаженный JSON отклоняется и выдается ошибка разбора.Начиная с jQuery 1.9, пустой ответ также отклоняется;сервер должен вернуть ответ null или {}.(См. Json.org для получения дополнительной информации о правильном форматировании JSON.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...