How can I get the value of a cookie in oracle from a request that was originated with ajax from a non-apex page (inside an apex server)?
I wanted to start by creating a function that returns the value of the login cookie and use that function to return the value to the browser to see that it can be done.
So I created a resource template and handler with the following source: select test() from dual.
The test function is declared as:
create or replace function test return varchar2
is
c owa_cookie.cookie;
begin
c := owa_cookie.get('LOGIN_USERNAME_COOKIE');
return c.vals(1);
end;
When I run select test() from dual from an sql commands window I get the value of the cookie, but when I send a request to the handler with ajax I get the following error:
An error occurred when evaluating the SQL statement associated with this resource. SQL Error Code 6502, Error Message: ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.OWA_UTIL", line 354
ORA-06512: at "SYS.OWA_COOKIE", line 59
ORA-06512: at "SYS.OWA_COOKIE", line 179
ORA-06512: at "<no need to see this>.TEST", line 5
I've been using the following call (checking the result through the network dev tools)
$.ajax({url: "<handler url here>"})
Update:
The reason I'm using a rest service is because the page that originates the request is not an apex application but it is on the same domain (so it has the same cookies).
This is what I think is happening: The cookie is sent as part of the http request header of your apex application call. The rest call is another http request, unrelated to your apex http request and I don’t believe the header of that request includes the cookie. So in the database session that is created as part of your rest request the cookie will not exist. You could probably set the header of the rest request yourself to fix this.
--UPDATE--
To check which cookies can be read, create a rest handler of source type pl/sql with the following source:
DECLARE
l_names owa_cookie.vc_arr;
l_vals owa_cookie.vc_arr;
l_num_vals INTEGER;
BEGIN
owa_cookie.get_all(
names => l_names,
vals => l_vals,
num_vals => l_num_vals);
APEX_JSON.open_array('cookies');
FOR r IN 1 .. l_names.COUNT LOOP
APEX_JSON.open_object; -- {
APEX_JSON.write('name', l_names(r));
APEX_JSON.write('value', l_vals(r));
APEX_JSON.close_object; -- } cookie
END LOOP;
APEX_JSON.close_array; -- ] cookies
END;
The apex username cookie is not in that list of cookies. I suggest you create your own custom cookie in an after-login process in apex.
I verified that a cookie set with the following code in an apex process is picked up by the rest handler (based on blog https://www.apex-at-work.com/2012/05/apex-simple-cookie-example.html)
begin
owa_util.mime_header('text/html', FALSE);
owa_cookie.send(
name => 'CUSTOM_USER_COOKIE',
value => :APP_USER,
expires => sysdate + 30 );
apex_util.redirect_url (
p_url => 'f?p=&APP_ID.:1:' || :SESSION,
p_reset_htp_buffer => false );
end;
To get a cookie from an AJAX request within APEX, you can use the OWA_COOKIE package, but you do not need to define any templates or handlers. It can all be done from within the page (or calling an external procedure from within the page). Below are the steps I used to get the JSESSIONID cookie.
I have built an example application on apex.oracle.com that you can check out.
Page Setup
The page is very simple with just one text box and one button. The button's action is set to Redirect to URL and this is the target:
javascript: apex.server.process("AJAX_TEST", { }, { success: function (pData) { console.log(pData); apex.item("P10_JSESSIONID").setValue(pData); }, dataType: "text", error: function (jqXHR, textStatus, errorThrown) { } }).always(function () { });
The javascript is calling the AJAX Callback (which is shown below) and storing the output in the P10_JSESSIONID page item as well as logging it to the browser console.
AJAX Callback Setup
The code in the AJAX Callback is very similar to the code you shared. I am getting the cookie then printing it out with HTP.P. This is all that is needed to return the value of the cookie to the page to be used for whatever you'd like. You can also make the code in the AJAX callback call a standalone procedure compiled into the database if you so choose.
Update
I updated my example application so that there will be a dropdown showing all of the cookies, then you can select from the list and click the button to send an AJAX request to get the value of that cookie.
Related
I am trying to logout a user using a JavaScript code but it keeps loading without logging out.What have I done wrong?
I have tried changing the function itself but it still wouldn't log out.The loader just keeps on running.
this is the code
logout.html(loader);
$.get("modules/"+role+"/"+role+".php",{
},function(pagedata){
logout.show().html(pagedata);
});
I'm expecting the code to logout and take me back to the login page.
The
$.get()
method requests data from the server with an HTTP GET request.
The required URL parameter specifies the URL you wish to request.
The optional callback parameter is the name of a function to be executed if the request succeeds.
$.get(URL,callback);
so change your code :
logout.html(loader);
$.get("modules/"+role+"/"+role+".php",function(pagedata){
logout.show().html(pagedata);
});
I am using Oracle 11g with Oracle Apex v4.2.2 and I was wondering how the best way to call an Oracle function via an ajax call, within a Dynamic Action.
I basically have a function that takes six parameters that either returns the result of 'INVALID' or 'VALID'.
Within my page, I want to be able to accept the values that the user has entered and once they press the button to process, I need to check via ajax whether the result was 'INVALID' or 'VALID' and immediately present the user with a dialog box notifying them that there was an error.
Is there a new means of processing this type of ajax request to call a function, within Oracle APEX v4.2.2?
Ajax + apex 4.2 = apex.server.process api
It requires you have a process at the on-demand process point of the page or an application process. In it you have to call your function and provide the parameters, which can be the page items. To provide a return, write values to the http buffer with calls to htp.p.
DECLARE
some_var1 VARCHAR2(50);
BEGIN
some_var1 := my_package.my_function(:P1_EMPNO, :P1_DEPTNO);
-- write values back
htp.p(some_var1);
END;
You can easily provide apex.server.process with page items. Further handling is all in javascript.
Note of warning: the dataType is by default set to JSON, and thus if you provide no other default datatype and do not return a json string you will get a parsing error. So if you return a text within your on-demand process such as INVALID, make sure to set the datatype to text!
apex.server.process ( "MY_PROCESS", {
pageItems: "#P1_DEPTNO,#P1_EMPNO"
}, {
dataType: "text"
, success: function( pData ) {
//pData should contain VALID or INVALID - alert it
alert(pData);
if ( pData === 'INVALID' ) {
// do something here when the result is invalid
// maybe you want to color something red for example
alert('The data you have entered is invalid');
};
}
} );
I wouldn't split this up in more dynamic actions than necessary, even though it might be possible. I personally am not fond of trying to use a PLSQL block dynamic true action, just because it is more obscure to act on if you want to deal with return values.
Just set your button to not submit the page, but action defined by dynamic action. Then in the dynamic action create one true action of type execute javascript, and use the ajax call with callback(s) there.
i am new to web development creating a kind of social networking website for college project. I want to include update the messages count in the message menu every time there is a new msg in the database for the user(like facebook message menu on homepage)
But it's frustrating learning ajax, however after searching on web and reading some topics from some books I came to the solution that i can make an $ajax call in my js file in the homepage and send data ('name'=>'user') stored in javascript cookie that i have created on loading of home page after the user login, to a php file which will search across the recent_msg table in database to fetch the recent message for the logged in user if any after fetching the php file will create the html file with code snippet and further another jquery code will append that snippet from file to the message list menu.
the PHP part is not the problem but how can i send the username to the php file using jquery ajax api, here is the code what i think i can apply but i am doubtful in that if this is the correct way
$(document).ready(function{
setInterval ( function()
{
var usr = getCookie("name");
$.ajax ( {
url: '/phpScripts/recent_msg.php',
type: 'POST',
data: usr,
success: function(data){
}
} );
},10);
});
what is the purpose of success function in the code?
data needs to be in the form of an object / key-value-pair (EDIT: or if a string, as a valid querystring). data: { name: usr }. However, since it's in a cookie, your PHP page will have direct access to that cookie. It's safer to let your session cookie tel the PHP page who the user is instead of relying on an AJAX call to tell the PHP page who it is.
http://php.net/manual/en/features.cookies.php
So I'd drop data from your AJAX call altogether, and in your PHP page, use $_COOKIE["name:"]
Then whatever HTML gets passed back from the PHP page will arrive in the data call. If it's HTML, then simply add it to your HTML to some message div, such as.
<div id="recent-messages"></div>
<script type="text/javascript">
$(document).ready(function{
setInterval ( function()
{
var usr = getCookie("name");
$.ajax ( {
url: '/phpScripts/recent_msg.php',
type: 'POST',
data: usr,
success: function(data){
$('#recent-messages').html(data);
}
} );
},10);
});
</script>
The success function executes whenever your ajax call completes successfully. This means that the page actually exists and no server-side errors occurred on the page. The variable data will contain whatever information is returned from the page on the sever /phpScripts/recent_msg.php. Generally this is either json or xml, but it entirely depends on your implementation of recent_msg.php.
If the user has to log in that means you have to have created a session. In that case you can store the logged in user's information such as their name in $_SESSION on the server and there is no need to store it as a cookie. Since $_SESSION is already on the server, there is no need to send that data via ajax in any case.
Is there any way to intercept an ajax request being made via jquery, to insert additional variables into it?
I know that .ajaxStart() lets you register a callback which triggers an event whenever an ajax request begins, but what I'm looking for is a way to cancel that ajax request if it meets certain criteria (e.g url), insert some more variables into its content, and then submit it.
This is for a plugin for a 3rd party software whose own code can't be changed directly.
Edit: Seems like .ajaxSetup() lets you set some global variables related to ajaxRequests. If I registered a beforeSend function, would that function be able to cancel the request to make a different one on meeting certain criteria?
Figured it out, this was the code I used:
jQuery(document).ready(function()
{
var func = function(e, data)
{
//data.data is a string with &seperated values, e.g a=b&c=d&.. .
//Append additional variables to it and they'll be submitted with the request:
data.data += "&id=3&d=f&z=y";
return true;
};
jQuery.ajaxSetup( {beforeSend: func} );
jQuery.post('example.php', {a : 'b'}, 'json');
} );
To cancel the request, returning false from func seemed to work.
Having trouble accessing javascript code in a mixed html/js ajax response. jQuery ajax doc states:
If html is specified, any embedded JavaScript inside the retrieved
data is executed before the HTML is returned as a string
Which I can confirm by adding a simple snippet to the html reply:
<script type="text/javascript"> alert($(this)); </script>
How then to retain access to the js code vs. one-and-done execution?? Trying to implement a modal login (to prevent data loss on session timeout in form submission screens). Of course I need to be able to access the ajax'd js code to then validate email/password fields and ajax authenticate user credentials on the remote server.
Here's the modal login coffeescript snippet:
# submit form
$.ajax
success: (data) -> ...
error: (data) ->
popAuth(data.responseText) if(data.status == 401)
popAuth = (title) ->
$.fancybox({
href: "/login"
ajax: { type: "GET" }
title: title
})
Perhaps I can add a success callback to popAuth() ajax options to store the returned js code? How about jQuery "live" handler? Unfortunate that this scenario is not as straight forward as one would hope ;-) I have seen $.getScript as an option, but would prefer to not separate html from js since server-side already assembles html + js and the original ajax call pulls it all down in one go. (i.e. avoid creating a dedicated server-side controller to send back js file content bundle)
I am of course open to alternative solutions to workaround this issue. For example, I could store login fields and js login validation code on every screen (JVM CRUD application living behind WordPress front end so every screen is basically auth required) in a hidden div, and then pop the modal login window "locally", which I assume would get around the annoying one-and-done js execution of remote ajax content.
Anyway, Ideas appreciated! client-side is both wonderfully simple and...horribly complex ;-)
Ok, fending off the veritable deluge of responses, I'll take a stab myself.
As I understand it now, since mixed html/js content is one-and-done executed, we have one chance to capture ajax response js code and bind it to current scope.
First, in the original ajax call (i.e. form submit that returns a potential 401 not authorized status) set the context of the modal login's ajax setup to $(this), the currently executing scope that contains jquery validation and other shared js code needed for modal login ajax submit to work.
In my case, using fancybox, adding context param it now looks like:
popAuth = (title) ->
$.fancybox({
href: "/login"
ajax: { type: "GET" }
context: $(#)
title: title
})
Then, since the parent window contains the majority of needed javascript, the only requirement is to create a js file that binds modal login form button click event to validation and $.ajax submission.
# login.coffee
jQuery ->
$('#loginSubmit').click (e) ->
e.preventDefault()
isValid = $('#loginForm').validate().form()
if isValid
$('#spinner').show()
$.ajax
data: $('#loginForm').serialize()
success: (data) ->
$('#status').fadeOut()
location.href = '/foo'
error: (data) ->
$('#status > div').html( data.responseText )
$('#status').fadeIn()
complete: () ->
$('#spinner').hide()
Done, all good, works ;-)