I have since discovered a much simpler and faster way to make cross domain
requests to web2py.
In jquery ajax there is a crossDomain parameter. If you set
crossDomain=True then you do not need to add the X-Requested-With header;
it only makes one call to the server reducing the response time by 30-50%;
you do not need to check for OPTIONS on the server;and you do not need to
set Access-Control-Allow-Credentials or Access-Control-Max-Age.
In summary all you need in your web2py controller is:
if request.env.http_origin:
response.headers['Access-Control-Allow-Origin'] =
request.env.http_origin # or restrict access to specific origins
.....do whatever you want
return dict()
On Thursday, 2 August 2012 09:56:31 UTC+1, simon wrote:
>
> Excellent thanks. That works either in the model or controller.
>
> You must also add the header suggested by Anthony to the ajax call. If
> you don't then not only is request.ajax=false but it does not do the two
> part request with OPTIONS and GET so does not set the access control
> headers and does not return any response.
>
> You can use "return" instead of "raise HTTP(200)".
>
> On Thursday, 2 August 2012 04:13:30 UTC+1, Massimo Di Pierro wrote:
>>
>> I think you want:
>>
>> if request.env.http_origin:
>> response.headers['Access-Control-Allow-Origin']
>> = request.env.http_origin
>> response.headers['Access-Control-Allow-Credentials'] = 'true'
>> response.headers['Access-Control-Max-Age'] = 86400
>> if request.env.request_method == 'OPTIONS':
>> if request.env.http_access_control_request_method:
>> response.headers['Access-Control-Allow-Methods']
>> = request.env.http_access_control_request_method
>> if request.env.http_access_control_request_headers:
>> response.headers['Access-Control-Allow-Headers']
>> = request.env.http_access_control_request_headers
>> raise HTTP(200) # not sure about this line
>>
>>
>> On Wednesday, 1 August 2012 18:24:33 UTC-5, simon wrote:
>>>
>>> I am making the call using jquery. You are correct that the X-Requested
>>> header is not included automatically and without it the request shows in
>>> chrome as a GET with response 303 redirect. If I explicitly add the
>>> X-Requested header then it shows as an "OPTIONS" request and instead of the
>>> headers it shows Access-Control-Request-Headers and the response
>>> is "load cancelled".
>>>
>>> I think the problem here is the security restrictions on cross-origin
>>> requests. The OPTIONS request expects a response that includes an
>>> Access-Control-Allow-Origin
>>> header from web2py. I know the magical incantations that are needed for
>>> this in PHP (as below) but am unclear how this can be done from web2py.
>>> The access_control headers do not appear to be included in request.env.
>>>
>>> Basically I need to do the web2py equivalent of this PHP code:
>>>
>>> if (isset($_SERVER['HTTP_ORIGIN'])) {
>>> header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
>>> header('Access-Control-Allow-Credentials: true');
>>> header('Access-Control-Max-Age: 86400'); // cache for 1 day
>>> }
>>> if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
>>> if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
>>> header("Access-Control-Allow-Methods:
>>> {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']}");
>>> if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
>>> header("Access-Control-Allow-Headers:
>>> {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
>>> }
>>> exit(0);
>>> }
>>>
>>>
>>> On Wednesday, 1 August 2012 22:42:07 UTC+1, Anthony wrote:
>>>>
>>>> Yes, you can make Ajax calls to web2py and get a response back -- and
>>>> that is independent of whether request.ajax is True. Here's the code used
>>>> to set request.ajax:
>>>>
>>>> x_req_with = str(request.env.http_x_requested_with).
>>>> lower()
>>>> request.ajax = x_req_with == 'xmlhttprequest'
>>>>
>>>> So, web2py checks whether the request headers include
>>>> "X-Requested-With: XMLHttpRequest". Perhaps for some reason your Ajax call
>>>> is not setting that header. web2py will still respond to the request, but
>>>> it won't set request.ajax to True unless that header is there. You could
>>>> either make sure that header is set when the request is made, or add some
>>>> other flag to the request that your application can use to determine the
>>>> type of request (e.g., a GET or POST variable). See
>>>> http://stackoverflow.com/questions/1885847/jquery-no-x-requested-with-xmlhttprequest-in-ajax-request-header
>>>> .
>>>>
>>>> Anthony
>>>>
>>>> On Wednesday, August 1, 2012 4:42:15 PM UTC-4, simon wrote:
>>>>>
>>>>> I have a page served by a php application where a button makes an ajax
>>>>> call to a web2py controller. However when it arrives the request.ajax
>>>>> field
>>>>> is false and it then tries to redirect to the login page.
>>>>>
>>>>> Is it possible to make an ajax call to a web2py server from a
>>>>> non-web2py page and send the response back to the callling page? Am I
>>>>> doing
>>>>> it wrong?
>>>>>
>>>>
--