Dear domino cognoscenti,
I've just written a simple xAgent using an xpage which works for GET requests but when I submit a POST request I get an Error 500 HTTP Web Server: Command Not Handled Exception
with the following detail CLFAD0384E: Page instance not found. The $$viewid ID was not present in a POST request
(thanks Per for the hint).
Here's the code. What am I doing wrong? Do xpages not handle POST requests by default? Do I have to enable this or something?
Thanks very much for your time! đ
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
<xp:this.resources>
</xp:this.resources>
<xp:this.afterRenderResponse>
<![CDATA[#{javascript:
var exCon = facesContext.getExternalContext();
var requestMethod = exCon.getRequest().getMethod();
var response = exCon.getResponse();
var writer = facesContext.getResponseWriter();
response.setContentType("text/plain");
response.setHeader("Cache-Control", "no-cache");
writer.write(requestMethod);
writer.endDocument();
}]]>
</xp:this.afterRenderResponse>
</xp:view>
Edited 16 October 2022 I've tried the following:
viewState="nostate"
to xp:view
. (thanks Mark for that)afterRenderResponse
other than logging - still
get the same problem.beforeRenderResponse
- same problem.restService
- same.The only thing that appears to fix it is:
$$viewid
and set this to the value '!!' or '!0!' or similar.Content-Type:multipart/form-data
.Sending it as plain text, application/json etc doesn't work. For some reason the xpage won't accept other encoding types.
Any ideas anyone?
The issue is with CSRF protection as detailed in this blog post. When creating an xpage, in xsp.properties
, the setting xsp.csrf.protection=true
needs to be set to false
(annoyingly it's not part of the UI, you have to go to the source tab).
The explainer from the blog post is as follows.
If you look in a new NSF the xsp.properties contains a setting xsp.csrf.protection=true .
This enables a built-in framework for CSRF protection đ and was very easily retrofitted to our existing NSFs.
When this feature is enabled every XPage contains a token such as
<input type=âhiddenâ name=â$$viewidâ id=âview:_id1__VUIDâ
value=â!1to6ah3iyy1uc2gquai14d7ik!â>
If the returned XPage does not have this same token then an error is generated. The error will be CLFAD0253E: Cannot find a page instance corresponding to the ID: $$viewid=!aaaaaaaaaa!. It may have expired. Try loading the web page
Setting this to false prevents this from occuring and the code works as expected (however see here for the multipart/form-data
) Obviously there are risks so this isn't ideal but it's the cause of the problem seen. Setting this from true to false stops this from occurring.
Thanks to Sean Cull at Focul for pointing this out. If following this path, we'd have to code our own CSRF token handler.
Thanks to everyone else who contributed above. I appreciate your time.