Is there an Yesod alternative for Rails' link_to foo, bar, method: "delete"?

Is there an easy way to create a link that uses a method different from GETYesod, for example, in Ruby on Rails, where can I make link_to foo, bar, method: "post"one that sends the link through JavaScript?

update: What Ruby on Rails does is that it generates an attribute data-method, which is then processed by its own JavaScript library. I'm not necessarily looking for the exact same solution, but if there is an existing mechanism for creating links POSTin Yesod.

+4
source share
2 answers

, Rails. : , Javascript , , CSRF . :

linkToPost :: Route App -> [(Text,Text)] -> Text -> Widget
linkToPost = linkToMethod "POST"

linkToMethod :: Text -> Route App -> [(Text,Text)] -> Text -> Widget
linkToMethod method url attributes content = 
    toWidget [hamlet|
    $newline never
    <a href="@{url}" rel="nofollow" data-method="#{method}" *{attributes}>#{content}</a>
    |]

:

^{linkToPost CommentR [] "Create comment"}

Javascript data-method. rails.js, . Javascript:

$(document).ready(function() {

  $(document).on("click", "a[data-method]", function() {
    var link = $(this);
    var method = link.data('method');

    handleMethod(link);
    return false;
  });
});

function handleMethod(link) {
  var href = link.attr('href'),
    method = link.data('method'),
    csrfToken = $('meta[name=csrf-token]').attr('content'),
    form = $('<form method="POST" action="' + href + '"></form>'),
    metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';

  if (csrfToken !== undefined) {
    metadataInput += '<input name="_token" value="' + csrfToken + '" type="hidden" />';
  }

  form.hide().append(metadataInput).appendTo('body');

  form.submit();
}

, POST _method, Yesod middleware _method, Rails. Javascript , .

CSRF-, Rails.js, CSRF <head>. -, CSRF defaultLayout:

mCsrfToken <- fmap reqToken getRequest

default-layout-wrapper.hamlet:

$maybe token <- mCsrfToken
  <meta name="csrf-token" content=#{token}>

CSRF, . , (, DELETE/users/1) CSRF, :

checkCsrf :: Handler ()
checkCsrf = do
    ((res, _), _) <- runFormPost (renderDivs (mempty :: AForm Handler () ))
    case res of
        FormSuccess _ -> return ()
        _ -> permissionDenied "CSRF failure"

+ , .

Update

, Yesod CSRF cookie , , , , HTML . :

  • cookie , HTML-.
  • POSTing JSON/ .. , .
  • Yesod
+4

, , GET Yesod

, .

POST- Yesod

POST , . , postLink :: Route -> Widget.

+5

All Articles