Using HTTP POST with typeahead js and bloodhound js
Asked Answered
C

2

7

By default, bloodhound.js will query via HTTP GET, but that leaves you vulnerable to JSON hijacking. Since I have sensitive information that I want to load into typeahead, HTTP GET leaves me vulnerable. There used to be an option for picking post (as shown here: typeahead.js remote beforesend post data issue), but that doesn't work with the latest version (v.0.11.1).

Chub answered 15/10, 2015 at 19:21 Comment(1)
C
17

It took me lots of heartache and experimenting to get this. In the latest version (v.0.11.1) there is a transport function option, you can use this to delegate to whatever you want (websockets, or plain old $.ajax with a post).

var accountBloodhound = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,

    remote: {
        url: '/account/search#%QUERY',
        wildcard: '%QUERY',
        transport: function (opts, onSuccess, onError) {
            var url = opts.url.split("#")[0];
            var query = opts.url.split("#")[1];
            $.ajax({
                url: url,
                data: "search=" + query,
                type: "POST",
                success: onSuccess,
                error: onError,
            })
        }
    }
});

$('#remote .typeahead').typeahead(null, {
    name: 'best-pictures',
    display: 'value',
    source: accountBloodhound 
}).bind('typeahead:select', function (ev, suggestion) {
    console.log('Selection: ' + suggestion);
});
Chub answered 15/10, 2015 at 19:21 Comment(5)
your heartache has paid-off ;)Clearstory
In your example transport takes the following (opts, onSuccess, onErro), where are they initialized. I am struggling hard to understand how onSuccess binds to source.Indented
@Indented - opts is an object that is created by typeahead and handed to your transport function. You can set a breakpoint/debugger command within the transport function. onSuccess and onError are just callback functions to use/call when the method is successful or errored. You can see that I just pass them off wholesale to my jquery ajax call, but you could call them if you so desired.Chub
Thank you for this lifesaver!Nerveracking
Hi @viggity, this is very helpful. But can I also pass an api-key here?Shearer
P
3

This Link will help

var searchAuto = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('word'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
        url: base_url + 'ajax/get_words',
        prepare: function (q, rq) {

            $(".typeahead-loader").show();

            rq.data = {
                q: $("#SearchData").val(),
                // source: 'S01',
                searchtype: $("#Searchtype").val(),
                language: $("#language").val(),
                author: $("#author").val(),
                raag: $("#raag").val(),
                page_from: $("#page_from").val(),
                page_to: $("#page_to").val()
            };
            return rq;
        },
        transport: function (obj, onS, onE) {

            $.ajax(obj).done(done).fail(fail).always(always);

            function done(data, textStatus, request) {
                // Don't forget to fire the callback for Bloodhound
                onS(data);
            }

            function fail(request, textStatus, errorThrown) {
                // Don't forget the error callback for Bloodhound
                onE(errorThrown);
            }

            function always() {
                $(".typeahead-loader").hide();
            }
        }
    }
});

if you console.log the obj, i.e, first param, you will get

enter image description here

and you can easily override the type in obj

obj.type = 'POST'

Hope this helps...

Platinocyanide answered 24/2, 2017 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.