2

I have several different forms that each return something different. I need to detect if it's a simple string (so i can put it in the error/status area) or if its javascript I do nothing and let it execute.

This is currently how I'm doing my checking, but I want to make sure this is 100% sturdy and reliable... I couldn't think of any other way.

The other option would be to always use JSON, but then I need a JSON shim, as well as somehow trying to serialize javascript into JSON.

  $.ajax({
    type: 'POST',
    url:  form.attr('action'),
    data: form.serialize()
  })
  .done(function(data, textStatus, xhr) {
    if (!xhr.getResponseHeader('Content-Type').match(/text\/javascript/i)) {
      form.find('.status').text(data).removeClass().addClass('status status-done').slideDown(200);
    } else { 
      // this is where i do nothing and let JS run
    }
  })

The following works, but I'm afraid there would be some edge case where it's not going to work (not sure what that might be, but it's important this section works 100%)

Tallboy
  • 11,480
  • 11
  • 67
  • 151
  • 2
    Why do you need a JSON shim? What ancient browsers you need to support? I think you're facing an XY problem here... – elclanrs Aug 30 '14 at 23:32
  • I'd recommend that you read up on ajax dataType's as it appears that you got some bad information. http://api.jquery.com/jquery.ajax/ – Bob Tate Aug 30 '14 at 23:38
  • How should I differentiate between JSON and application/javascript then? – Tallboy Aug 30 '14 at 23:53
  • @Tallboy The server/application should be responding with [`Content-Type: application/json`](http://stackoverflow.com/questions/477816/what-is-the-correct-json-content-type) or at least similar for JSON. (Unless it's [JSON-P](http://json-p.org/).) – Jonathan Lonowski Aug 30 '14 at 23:55
  • I know that, but my question revolves around... what is the best way to have my .done() ajax promise determine if the response is application/json (show the error message above the form), or... application/javascript (do nothing and let the JS execute. i dont want to be injecting the response JS into the form so i need to determine the content type) – Tallboy Aug 30 '14 at 23:58
  • Does each POST endpoint return the same content type each time or does it differ? For instance, if the action is "/doSomething" will doSomething always return JavaScript or does it depend on something else? – jmort253 Aug 31 '14 at 01:09
  • well I have 5 forms that all are controlled with 1 ajax function (for simplicity). I have decided to just use json though, without having any JS in the body. Instead is set a few special json properties and then just parse that in the script. My last question is, so my script is safe and jquery is using $.parseJSON right? I dont need any shims? – Tallboy Aug 31 '14 at 01:19
  • If you're using JSON.parse (or parseJSON if you insist on using a library) then it will toss out anything with a function in it. JSON can only contain strings, arrays, numbers and other objects that only contain those things, so yes, you're safe. Hope this helps! – jmort253 Aug 31 '14 at 04:22
  • If interpret Question , determine if response within json reposne `string` ? js not in response ? , only variables as string within json responses ? If response `text/javascript` , jquery ajax create `script` tag , run script , remove script tag ? , `data` not processed through `.done(fn(data){})` ? If possible, can detail requirement ? Thanks – guest271314 Aug 31 '14 at 05:07

1 Answers1

1

Note, Not certain about detail of requirement . If interpret Question correctly , at different form elements , different response types from $.ajax() requests ? a) Check for response type string ? b) do nothing ?

Could possibly check for response type string within json response with

if (typeof data.data === "string") { 
  // do stuff , with `string`
}

if $.ajax() expect json response , receive js , could possible run the piece immediately. At piece below , first response is string , filtered through if at .done() . Second response json object having a js function expression as property , which appear to run immediately , at $.ajax() success textStatus . Still capable to check response type of object at else , though , run as script . See empty xhr.repsonseText and xhr.reponseJSON at console

Try

var urls = [["/echo/json/","abc"]
            , ["/echo/json/",
              {"abc": 
                (function() { 
                    setTimeout(function() {
                        $("body").append("<div id=data>" 
                        + "object" + "</div>"); 
                        $("#data")
                        .hide(0)
                        .fadeIn(1200)},1200) 
                 }())
               }]
            ];


    var request = function(url, _data) {
    $.ajax({
        type: 'POST',
        url:  url,
        data: {json : JSON.stringify({"data":_data})}
      })
      .done(function(data, textStatus, xhr) {
        if (typeof data.data === "string") {
            $("body").append("<div>" + data.data + "</div>")
        } else { 
            console.log(typeof data.data
                        , data
                        , xhr.responseText
                        , xhr.responseJSON);
          // this is where i do nothing and let JS run
        }
      })
    };

    $.each(urls, function(k, v) {
      request(v[0], v[1])
    });

jsfiddle http://jsfiddle.net/guest271314/y9b7t740/

See

jQuery getScript() vs document.createElement('script') , script.js

Calling a JavaScript function returned from an Ajax response

jQuery: Evaluate script in ajax response

What is JSONP all about?

Community
  • 1
  • 1
guest271314
  • 1
  • 10
  • 82
  • 156