Second request is not working in dojo.io.iframe.send in dojo 1.7 - dojo

I am uploading a file using dojo.io.iframe.send ajax call using below code.
Am using dojo 1.7 and WebSphere Portal Server 8.0
dojo.io.iframe.send({
form: "workReqIDFormWBS",
handleAs: "text/html",
url:"<portlet:actionURL/>",
load: function(response, ioArgs) {
console.log(response, ioArgs);
return response;
},error: function(response, ioArgs) {
console.log(response, ioArgs);
return response;
}
});
When am uploding the file for the first time it's working fine,where as from second time onwards nothing is happening. Any solution for this issue.

Action URLs are only valid to be invoked once by default. Portal protects against form submission replay incidents by internally assigning an ID within the action URL produced.
You should also be seeing some logging on those subsequent action url requests: http://www-01.ibm.com/support/docview.wss?uid=swg21613334
I suggest either using resource URL and serveResource() in your portlet or ensuring that your response from the render phase following the action URL processing regenerate the Action URL value and update a variable your posted javascript reads and uses in subsequent send() calls.

Related

Nuxt SSR - i can't check if a user is authenticated

I'm trying to work on a Nuxt SSR frontend that uses a Django backend with Session Authentication.
I would like to have some SSR pages as well as client rendered pages in my frontend, so i'm using Universal mode.
The problem is that i did not find a working approach to check if a user is authenticated before loading a page, so i can't restrict pages to anonymous users. In order to check if a user is authenticated, Django will check if the request's headers contain a cookie, and according to that return if the user is authenticated or not.
Here is what i tried:
1) Middleware
export default async function ({context, redirect}) {
axios.defaults.withCredentials = true;
return axios({
method: 'get',
url: 'http://127.0.0.1:8000/checkAuth',
withCredentials: true,
}).then(function (response) {
//Redirect if user is authenticated
}).catch(function (error) {
console.log(error)
});
}
Here i'm sending a request to my backend to check if the user is authenticated. The problem is that the middleware is executed from server side, which means there will never be any cookie in the request, even if the user is authenticated. This means that every time i refresh the page, according to the middleware the user is always anonymous, even when the user is authenticated.
2) Plugin
export default function (context, inject) {
if (process.client){
console.log('client')
return axios({
method: 'get',
url: 'http://127.0.0.1:8000/checkAuth',
withCredentials: true,
}).then(function (response) {
//IF AUTHENTICATED, REDIRECT
context.redirect('/')
}).catch(function (error) {
console.log(error)
});
} else {
console.log('server')
}
}
Here i'm trying the same but with a plugin, and i'm "forcing" the plugin to check if the user is authenticated on the backend only when the plugin executes from client side. This works, cookies are sent in the headers and Django receives the cookie, but the problem with this solution is that Nuxt doesn't allow redirecting to other pages from a plugin (https://github.com/nuxt/nuxt.js/issues/4491).
3) Using beforeMount() in Vue
I tried to do that using beforeMount() from my Vue pages, but the problem is that since it will execute AFTER idration, the page will be loaded and after 1/2 seconds the redirect happens, which is kind of ugly.
Is it possible that there isn't a way to do this? Any kind of advice is appreciated
EDIT: the problem is not that i don't know how to code this, the problem is that when Nuxt sends a request to my backend from the server side middleware, the request will not contain any cookie, and because of this my Django backend cannot check the session cookie, which means that the backend cannot check whether or not the user is authenticated. The same code works when the middleware is executed from client side (if i navigate directly to the page instead of refreshing), because the request will contain the cookies.
I'm trying to understand if this is normal or not, but this could be an issue with Nuxt.
I know this a year old question and it was probably about nuxt 2, now nuxt 3 is out and running and I found my self with the same problem and here is how I solved it, just in case someone stumble here just like I did.
With Nuxt 3 server side you can use useFetch with the options headers: useRequestHeaders(['cookie'])
const { data, error, pending, refresh } = await useFetch(api.auth,
{
credentials: "include",
headers: useRequestHeaders(['cookie'])
}
);
There are a few issues you need to be aware of:
_ The cache, if you perform the same request with the same parameters it will return the same cached response (it won't even call the end point API). Try to use the key option with different values or the returned refresh method and check the doc "Data fetching" for more info.
_ The cookies, any cookie generate server side won't be shared with the client side, this means if the API generate a new token or session cookie on server side the browser won't receive those cookies and may generate new ones, this may get you in some 400 - bad request if you use session with CSRF, check this issue for more info.
I do have a working middleware with this
export default ({ redirect, store }) => {
if (store?.$auth?.$state?.loggedIn) {
redirect('https://secure.url')
} else {
redirect('https://login.please')
}
})

Force reload cached image with same url after dynamic DOM change

I'm developping an angular2 application (single page application). My page is never "reloaded", but it's content changes according to user interactions.
I'm having some cache problems especially with images.
Context :
My page contains an editable image list :
<ul>
<li><img src="myImageController/1">Edit</li>
<li><img src="myImageController/2">Edit</li>
<li><img src="myImageController/3">Edit</li>
</ul>
When i want to edit an image (Edit link), my dom content is completly changed to show another angular component with a fileupload component.
The myImageController returns the LastModified header, and cache-control : no-cache and must-revalidate.
After a refresh (hit F5), my page does a request to get all img src, which is correct : if image has been modified, it is downloaded, if not, i just get a 304 which is fine.
Note : my images are stored in database as blob fields.
Problem :
When my page content is dynamically reloaded with my single page app, containing img tags, the browser do not call a GET http request, but immediatly take image from cache. I assume this a browser optimization to avoid getting the same resource on the same page multiple times.
Wrong solutions :
The first solution is to add something like ?time=(new Date()).getTime() to generate unique urls and avoid browser cache. This won't send the If-Modified-Since header in the request, and i will download my image every time completly.
Do a "real" refresh : the first page load in angular apps is quite slow, and i don't to refresh all.
Tests
To simplify the problem, i trying to create a static html page containing 3 images with the exact same link to my controller : /myImageController/1. With the chrome developper tool, i can see that only one get request is called. If i manage to get mulitple server calls in this case, it would probably solve my problem.
Thank you for your help.
5th version of HTML specification describes this behavior. Browser may reuse images regardless of cache related HTTP headers. Check this answer for more information. You probably need to use XMLHttpRequest and blobs. In this case you also need to consider Same-origin policy.
You can use following function to make sure user agent performs every request:
var downloadImage = function ( imgNode, url ) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 304) {
var blobUrl = URL.createObjectURL(xhr.response);
imgNode.src = blobUrl;
// You can also use imgNode.onload callback to release blob resources.
setTimeout(function () {
URL.revokeObjectURL(blobUrl);
}, 1000);
}
}
};
xhr.send();
};
For more information check New Tricks in XMLHttpRequest2 article by Eric Bidelman, Working with files in JavaScript, Part 4: Object URLs article by Nicholas C. Zakas and URL.createObjectURL() MDN page and Same-origin policy MDN page.
You can use the random ID trick. This changes the URL so that the browser reloads the image. Not that this can be done in the query parameters to force a full cache break or in the hash to allow the browser to re-validate the image from the cache (and avoid re-downloading it if unchanged).
function reloadWithCache(img: HTMLImageElement, url: string) {
img.src = url.replace(/#.*/, "") + "#" + Math.random();
}
function reloadBypassCache(img: HTMLImageElement, url: string) {
let sep = img.indexOf("?") == -1? "?" : "&";
img.src = url + sep + "nocache=" + Math.random()
}
Note that if you are using reloadBypassCache regularly you are better off fixing your cache headers. This function will always hit your origin server leading to higher running costs and making CDNs ineffective.

Jsreport : Cannot get certain Respond Header

I am using Jsreport via API.
From the browser, a ajax call is made to jsreport server. The server answers with POST respond with data and a Header tag Permanent-Link which has the file locaton.
Copy paste it to the browser allow me to view the pdf file.
The problem it that I want to view it automatically in success handler of ajax call, but xhr.getRespondHeader() does not allow any other header than Content-Type. The respond header even have "Access-Control-Allow-Origin: *" already.
How can I get the pdf out for user?
You can use official jsreport browser client - http://jsreport.net/learn/browser-client
If it is loaded in the page, opening a report is as simple as this
jsreport.serverUrl = 'http://localhost:3000';
var request = {
template: {
content: 'foo', engine: 'none', recipe: 'phantom-pdf'
}
};
//display report in the new tab
jsreport.render('_blank', request);
You can also check its source code if you are curious how it is handling AJAX
https://github.com/jsreport/jsreport-browser-client-dist

Sailsjs socketio http status

I know I can call REST API of sails using socket.io. And return me the response. Following is a simple way to do that
socket.get("/", function (response) { console.log(response); })
But I also want the http status code along with response how I can get that?
If you're using the API blueprints, then the response will return the status code in the event of an error. For example, if there was a general server error, you'll get back:
{status: 500}
Otherwise, you'll get data in the response and you can assume the status was 200.
If you're using a custom controller action, then you can use any of the default responses (like res.serverError(), res.forbidden(), etc) to send back a status code, or you can set one yourself:
myAction: function (req, res) {
return res.forbidden(); // Will send {status: 403}
// OR
return res.json({status:400, error: 'Bad request!'})
}
But if you just send the status using res.json(500, {error: 'someError'}), you won't be able to retrieve it on the client.
Update
On Sails v0.10.x, using the new Sails socket client library, the request methods (io.socket.get, io.socket.post, etc) have callbacks that accept two arguments: the first being the response body (equivalent to the response in the previous client library version), and the second being an expanded response object which includes the status code, headers and more.

dojo.io.iframe.send does not send a request on second time onwards in dojo 1.8

Example code snippet
this._deferred = dojo.io.iframe.send({
url: "/Some/Servie",
method: "post",
handleAs: 'html',
content: {},
load: function(response, ioArgs){
//DO successfull callback
},
error: function(response, ioArgs){
// DO Failer callback
}
});
Steps
click submit button send a request and successfully got a response
click submit button again...request never send...
Appreciate any help
I can't talk for 1.8, but I am using dojo 1.6 and had a very similar issue that I resolved with the following method:
dojo.io.iframe._currentDfd = null; //insert this line
dojo.io.iframe.send
({...
*verified in Chrome Version 25.0.1364.152 m
Source: http://mail.dojotoolkit.org/pipermail/dojo-interest/2012-May/066109.html
dojo.io.frame.send will only send one request at a time, so if it thinks that the first request is still processing (whether it actually is or not), it won't work on the second call. The trick is to call cancel() on the returned deferred result if one exists, like so:
if (this._deferred) {
this._deferred.cancel();
}
this._deferred = dojo.io.iframe.send({
....
that will cancel the first request and allow the second request to send properly.
For dojo 1.8, dojo.io.iframe is deprecated. dojo.request.iframe is used instead.
And the solution from #Sorry-Im-a-N00b still works:
iframe._currentDfd = null;
iframe.get(url, {
data: sendData,
});