Setting up nginx to enable CORS for a specific function?

469 views
Skip to first unread message

Spokes

unread,
Oct 26, 2016, 2:19:38 PM10/26/16
to web2py-users
This isn't necessarily a web2py-specific question, but perhaps there's a web2py-specific solution that's preferable to other solutions, so I thought I'd ask it here.

I have some HTML code and javascript, which I'd like to be able to paste into any website, and which should access an API endpoint on a web2py server. The web2py application is running on an nginx server.

The javascript portion of the client code snippet is as follows:

<script>
    $
(document).on("click", "button", function(e){
                       
...
                       
var xhr = new XMLHttpRequest();
                        xhr
.open("POST", "https://myurl.com/api/action/");    
                        xhr
.setRequestHeader("Content-Type", "application/json");
                       
var jsonStr = JSON.stringify({
                           
Header:{Procedure:"..."},
                           
Body: { ... }
                       
});
                        xhr
.send(jsonStr);
                   
});
</script>

When the button that triggers the above action is clicked, the following error is generated (in Chrome):

XMLHttpRequest cannot load https://myurl.com/api/action. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.

As I understand it, this issue can be resolved by enabling CORS in the nginx settings. However, I'd like to limit the modification to that one API function, which corresponds to the application/controller/function combo, "[MyApplication]/api/action". I'd appreciate recommendations on how to do this within the context of web2py running on nginx. Alternatively, is there a modification to the client javascript code (I'd like to keep the code small, so any modification would have to not exceed a couple of lines) that would remedy the problem? Thanks.

Michele Comitini

unread,
Oct 26, 2016, 4:01:06 PM10/26/16
to web...@googlegroups.com
You can do that easily in web2py...

Below is a sample of a decorator that allows any origin.
Change it to fit your needs.

You can use in a controller like:

@cors_allow
def action():
   .
   .
   .
   return dict(...)

------------------

def cors_origin():
    origin = request.env.http_origin
    headers = {}
    headers['Access-Control-Allow-Origin'] = origin

    headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS, POST, HEAD, PUT'
    headers['Access-Control-Allow-Headers'] = 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Accept'
    headers['Access-Control-Allow-Credentials'] = 'true';
    response.headers.update(headers)

    if request.env.request_method == 'OPTIONS':
        headers['Content-Type'] = None
        raise HTTP(200, '', **headers)


def cors_allow(action):

    def f(*args, **kwargs):
        cors_origin()
        return action(*args, **kwargs)

    f.__doc__ = action.__doc__
    f.__name__ = action.__name__
    f.__dict__.update(action.__dict__)

    return f


--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Spokes

unread,
Oct 27, 2016, 11:17:18 AM10/27/16
to web...@googlegroups.com


Thanks, Michele; that worked like a charm! The only issue is that request.vars is empty - any idea as to what could be causing that?

Michele Comitini

unread,
Oct 27, 2016, 1:43:41 PM10/27/16
to web...@googlegroups.com
You did not POST any multipart/mime or form encoded var so no request.vars.
you should probably read the request.body content for JSON.

try to look into restful services or json services (see the book) to have that done automagically...




2016-10-27 17:17 GMT+02:00 Spokes <spoke...@gmail.com>:


Thanks, Michele; that worked like a charm! The only issue is that request.vars is empty - any idea as to what could be causing that?
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Spokes

unread,
Oct 27, 2016, 2:31:14 PM10/27/16
to web2py-users
For reasons that are not entirely clear to me yet, request.vars suddenly started showing the expected content...

Thanks, I'll read up on the Restful and json services portions of the book.

leandro....@gmail.com

unread,
May 1, 2019, 9:29:47 AM5/1/19
to web2py-users
Thanks Michele, although is an old post you saved my day!! :-)
To unsubscribe from this group and stop receiving emails from it, send an email to web...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages