Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POST calls do not change URL #243

Open
legacybass opened this issue Jan 29, 2015 · 1 comment
Open

POST calls do not change URL #243

legacybass opened this issue Jan 29, 2015 · 1 comment

Comments

@legacybass
Copy link

Given a series of pages in an SPA, if one of them tries to POST data to another page, the URL doesn't change. For example, if I am currently on /MyApp/#/Login and try to post the user data to /MyApp/#/OtherPage, the url will remain as /MyApp/#/Login. The page will correctly change, the route handlers are correctly called, and the login data is correctly passed, but the url remains the same.

Here's a jsfiddle that demonstrates the problem: http://jsfiddle.net/legacybass/25u8ye83/

@aplicacionamedida
Copy link

This strange behaviour only happens with verbs different to GET.

I think that this behaviour is a feature for these reasons:

  • POST methods normally means a change on a resource. It doesn't make sense to navigate to this kind of URLS because the meaning is to change some resource.
  • POST methods can contains very long data in the body , and maybe it's not possible to encode this data in the hash of the URL. There is normally a limit in the size of the hash. Some browsers can guive you an error if the hash is too long.

I want to explain this behaviour:
Short answer:

 setLocation() is not called for verbs different than GET.

Long answer:
The function Sammy.Application.run() has these lines of code (line numbers 996-1001):

      // bind to submit to capture post/put/delete routes
      this.bind('submit', function(e) {
        if ( !Sammy.targetIsThisWindow(e, 'form') ) { return true; }
        var returned = app._checkFormSubmission($(e.target).closest('form'));
        return (returned === false) ? e.preventDefault() : false;
      });

They are binding all submit events to an anonymous function. Observe that this anonymous function has a call to this other function:

Sammy.Application._checkFormSubmission()

This function is the responsible of this behaviour:

    _checkFormSubmission: function(form) {
      var $form, path, verb, params, returned;
      this.trigger('check-form-submission', {form: form});
      $form = $(form);
      path  = $form.attr('action') || '';
      verb  = this._getFormVerb($form);

      if (this.debug) {
        this.log('_checkFormSubmission', $form, path, verb);
      }

      if (verb === 'get') {
        params = this._serializeFormParams($form);
        if (params !== '') { path += '?' + params; }
        this.setLocation(path);
        returned = false;
      } else {
        params = $.extend({}, this._parseFormParams($form));
        returned = this.runRoute(verb, path, params, form.get(0));
      }
      return (typeof returned == 'undefined') ? false : returned;
    },

These are the important lines:

      if (verb === 'get') {
        params = this._serializeFormParams($form);
        if (params !== '') { path += '?' + params; }
        this.setLocation(path);
        returned = false;
      } else {
        params = $.extend({}, this._parseFormParams($form));
        returned = this.runRoute(verb, path, params, form.get(0));
      }
      return (typeof returned == 'undefined') ? false : returned;

If verb is "get" then _checkFormSubmission() change the location:

this.setLocation(path);

If verb is not "get" ,the the location is not changed. (runRoute() doesn't change the location.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants