Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
JSONP in Flask
import json
from functools import wraps
from flask import redirect, request, current_app
def support_jsonp(f):
"""Wraps JSONified output for JSONP"""
@wraps(f)
def decorated_function(*args, **kwargs):
callback = request.args.get('callback', False)
if callback:
content = str(callback) + '(' + str(f(*args,**kwargs).data) + ')'
return current_app.response_class(content, mimetype='application/javascript')
else:
return f(*args, **kwargs)
return decorated_function
# then in your view
@default.route('/test', methods=['GET'])
@support_jsonp
def test():
return jsonify({"foo":"bar"})
@bivald

This comment has been minimized.

Copy link

commented Oct 27, 2012

Works like a charm, for those of us who don't return a dictionary with "data" and instead returns dump_json output, just change:

content = str(callback) + '(' + str(f(args,*kwargs).data) + ')'

to

content = str(callback) + '(' + str(f(args,*kwargs)) + ')'

@uolter

This comment has been minimized.

Copy link

commented Nov 23, 2012

Hi,

as far as I saw you always return an http status code equals to 200. When I use the POST method I'd like to have a 201 response. Provided that a changed a little bit your code:

from functools import wraps
from flask import request, current_app

def jsonp(func):
"""Wraps JSONified output for JSONP requests."""
@wraps(func)
def decorated_function(_args, *_kwargs):
callback = request.args.get('callback', False)
if callback:
res = func(_args, *_kwargs)
data = str(res.data)
content = str(callback) + '(' + data + ')'
mimetype = 'application/javascript'
response = current_app.response_class(content, mimetype=mimetype, status=res.status_code)
return response
else:
return func(_args, *_kwargs)
return decorated_function

@Zerstoren

This comment has been minimized.

Copy link

commented May 24, 2013

Why you create so many code?
It is simply, in flask, only decorator and it work!

import flask
def jsonp(func):
  def decorated_function(*args, **kwargs):
        return flask.jsonify(func(*args, **kwargs))
  return decorated_function

@jsonp
def someController():
  return {'json': 'object'}

Move jsonp function in your libs or helpers packeg and only use.

@lxyu

This comment has been minimized.

Copy link

commented Sep 11, 2013

@Zerstoren where is your callback for jsonp?

@ehrlichja

This comment has been minimized.

Copy link

commented Oct 22, 2013

Thanks for this!

@lifenglifeng001

This comment has been minimized.

Copy link

commented Mar 16, 2015

cool!

@goodmami

This comment has been minimized.

Copy link

commented Dec 14, 2015

Response.data should not be used for recent versions of Werkzeug (and thus Flask). So the following uses get_data() and set_data(). Furthermore, using get_data(as_text=True) makes it work with Python3 as well as Python2. I also just modify the original request instead of creating a new one. Is there something wrong with doing that?

def jsonp(func):
    """Wraps JSONified output for JSONP requests."""
    @wraps(func)
    def decorated_function(*args, **kwargs):
        callback = request.args.get('callback', False)
        if callback:
            resp = func(*args, **kwargs)
            resp.set_data('{}({})'.format(
                str(callback),
                resp.get_data(as_text=True)
            ))
            resp.mimetype = 'application/javascript'
            return resp
        else:
            return func(*args, **kwargs)
    return decorated_function
@jarrekk

This comment has been minimized.

Copy link

commented Dec 25, 2016

@aisipos
Based on your gist, I edit some place to make json response can contain status code, please see my fork https://gist.github.com/JiaKunUp/a9df722bad15c61ea555fa860997edc9

@LindezaGrey

This comment has been minimized.

Copy link

commented Aug 22, 2019

good job, helped me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.