Handling GET 301/302 responses with JavaScript in Vue.js - vue.js

I need to print some 301/302 response headers with JavaScript: I saw lots of answers for Angular, but I’m using Vue.js to get the results. Well, it doesn’t really matter since it’s mainly a JavaScript issue… I mean, I’m not just interested in a Vue.js-only solution, it could and should work everywhere. As a front-end developer, I can’t manually create a scenario in which my project returns a redirect in its own server and finding a random remote page that does it without CORS limitations is hard. To be even more clear, I need to get status code and statusText of 301/302 responses (as well as the Location of the new page) before the redirection, then the full headers of the redirected page. Now I can retrieve only these last, because the default this.$http.get(); request created by vue-resource doesn’t seem to store the first in an object. What I’m asking here is if there’s a way to store the redirection response in a variable too, then to show both. I don’t know if switching to axios could be preferrable — since I’m pretty new to Vue.js. My component’s method is as follow:
getRequest: function() {
this.$http.get(this.url)
.then(function(response) {
if (response.ok) {
if (response.status === 301 || response.status === 302) {
// show the redirecting response
}
// show the redirected response
}
}
EDIT: the sources for this project are on GitHub; when you send a GET request and the response says 301/302, you should be able to see three columns instead of two where the second shows details of the redirecting response headers.

You are not able no handle 301 or 302 status because those are inside the
if(response.ok)
block, which means that the status is 200. Try this instead:
getRequest: function() {
this.$http.get(this.url)
.then(function(response) {
if (response.ok) {
// show the redirected response
}
if (response.status === 301 || response.status === 302) {
// show the redirecting response
}
}

Related

how solve 404 error in axios post request in vue?

i want send request to an api but i have 404 erro and i have nothing in network
can you help me?
my code:
loginMethod() {
const config = {
userName: "test#gmail.com",
password: "1234test",
};
return new Promise((resolve) => {
ApiService.post("api/authentication/login", config)
.then(({ data }) => {
console.log(data);
resolve(data);
})
.catch(({ response }) => {
console.log(response);
});
});
},
and ApiService function:
post(resource, params) {
console.log(params);
const headers = {
"E-Access-Key": "bb08ce8",
};
return Vue.axios.post(`${resource}`, params, { headers: headers });
},
Based only on what I can see in your code, you are not telling axios the complete URL if I'm right about it, and you didn't declare it somewhere else do this:
axios.post('yourdomain.com/api/authentication/login',params)
or
axios({
url:'yourdomain.com/api/authentication/login',
method:post,
data:{}
})
or
in your main js file or any other file that you import axios (if you are sharing an instance of it globali):
axios({baseurl:'yourdomain.com'})
and then you don't need to write the complete url everywhere and just insert the part you need like you are doing now and axios will join that address with the baseurl,I hope it helps
I guess the URL "api/authentication/login" might be wrong and the correct one would be "/api/authentication/login" that starts with /.
404 error means the resource referred by the URL does not exist. It happens when the server has deleted the resource, or you requested a wrong URL accidentally, or any wrong ways (e.g. GET vs POST)
To make sure if you were requesting to the correct URL (and to find where you're requesting actually), open Google Chrome DevTools > Network panel. You might need reload.
The url api/xxx is relatively solved from the URL currently you are at. If you were at the page http://example.com/foo/bar, the requested URL becomes http://example.com/foo/bar/api/xxx. Starting with / means root so http://example.com/api/xxx.
This answer might help to understand the URL system: https://stackoverflow.com/a/21828923/3990900
"404" means your API Endpoint is not found. You need to declare the location of your API Endpoint exactly. For example: http://localhost:8080/api/authentication/login.

Nuxtjs/Vuejs with axios trying to access URL results in Access to XMLHttpRequest at has been blocked by CORS policy

I am aware there are many answers related to this question but since nothing seems to work I am posting here.
I have NuxtJS/Vuejs application within which users can provide the GitHub URL (mostly the URL will contain the XML/JSON files). After getting the URL, I want to make a request to the URL using the axios and obtain the data present within the URL.
When I try to make a request i get the following error:
Access to XMLHttpRequest at 'GitHub URL' from origin 'http://localhost:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'Some GITHUB URL', but only one is allowed.
When I provide the same URL in the browser then I get the 302 status and obtain the raw JSON/XML data after redirection. I want to implement the same in my code.
If data is not found in the URL then obtain the redirection URL from the response and make another request with the new URL. But due to the CORS error and other error GET GIT HUB URL net::ERR_FAILED I am unable to get the response.
I tried many things mentioned on the website such as:
Adding proxy as mentioned here: https://stackoverflow.com/a/55481649/7584240
Adding a prefix to URL as mentioned here: https://stackoverflow.com/a/56781665/7584240
Adding the condition to axios as mentioned here: https://stackoverflow.com/a/48293817/7584240
And many other things but nothing seems to work for me and getting the same error. Can someone please help me with this issue?
Following is the sample code I have (The code is part of VUEX Store actions):
export const actions = {
obtainURLData ({ commit, state, dispatch, rootState }, inputURL) {
axios
.get(inputURL)
.then((response) => {
console.log('INSIDE RESPONSE')
console.log(response)
console.log(response.data)
if (response.status === 200) {
}
})
.catch((error) => {
console.log('INSIDE ERROR')
console.log(error)
console.log(error.response)
console.log(error.response.data.detail)
console.log(error.response.status)
})
}
}

Vue PWA caching routes in advance

I'm hoping someone can tell me if I'm barking up the wrong tree. I have built a basic web app using Vue CLI and included the PWA support. Everything seems to work fine, I get the install prompt etc.
What I want to do, is cache various pages (routes) that user hasn't visited before, but so that they can when offline.
The reason here is that I'm planning to build an app for an airline and part of that app will act as an in flight magazine, allowing users to read various articles, however the aircrafts do not have wifi so the users need to download the app in the boarding area and my goal is to then pre cache say the top 10 articles so they can read them during the flight.
Is this possible? and is PWA caching the right way to go about it? Has anyone does this sort of thing before?
Thanks in advance
To "convert" your website to an PWA, you just need few steps.
You need to know that the service worker is not running on the main thread and you cant access for example the DOM inside him.
First create an serviceworker.
For example, go to your root directory of your project and add a javascript file called serviceworker.js this will be your service worker.
Register the service worker.
To register the service worker, you will need to check if its even possible in this browser, and then register him:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/serviceworker.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope');
}, function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
}
In vue.js you can put this inside mounted() or created() hook.
If you would run this code it will say that the service worker is successfully registered even if we havent wrote any code inside serviceworker.js
The fetch handler
Inside of serviceworker.js its good to create a variable for example CACHE_NAME. This will be the name of your cache where the cached content will be saved at.
var CACHE_NAME = "mycache_v1";
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open(CACHE_NAME).then(function(cache) {
return cache.match(event.request).then(function (response) {
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
});
});
})
);
});
Everytime you make a network request your request runs through the service worker fetch handler here first. You need to response with event.respondWith()
Next step is you first open your cache called mycache_v1 and take a look inside if there is a match with your request.
Remember: cache.match() wont get rejected if there is no match, it just returns undefined because of that there is a || operator at the return statement.
If there is a match available return the match out of the cache, if not then fetch() the event request.
In the fetch() you save the response inside the cache AND return the response to the user.
This is called cache-first approach because you first take a look inside the cache and in case there is no match you make a fallback to the network.
Actually you could go a step further by adding a catch() at your fetch like this:
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
})
.catch(err => {
return fetch("/offline.html")
});
In case there is nothing inside the cache AND you also have no network error you could response with a offline page.
You ask yourself maybe: "Ok, no cache available and no internet, how is the user supposed to see the offline page, it requires internet connection too to see it right?"
In case of that you can pre-cache some pages.
First you create a array with routes that you want to cache:
var PRE_CACHE = ["/offline.html"];
In our case its just the offline.html page. You are able to add css and js files aswell.
Now you need the install handler:
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
return cache.addAll(PRE_CACHE);
})
);
});
The install is just called 1x whenever a service worker gets registered.
This just means: Open your cache, add the routes inside the cache. Now if you register you SW your offline.html is pre-cached.
I suggest to read the "Web fundamentals" from the google guys: https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook
There are other strategies like: network-first
To be honest i dont know exactly how the routing works with SPAs because SPA is just 1 index.html file that is shipped to the client and the routing is handled by javascript you will need to check it out witch is the best strategie for your app.

express api responds to GET and POST but not PUT and DELETE through cors but responds properly when the request is local

When I'm sending a request to my express API through Axios, the GET and POST request respond correctly, but PUT and DELETE does not.
This is not a code problem as all my tests are passing, I believe this is related to CORS
I have installed morgan npm package to log the requests to the server.
The GET and POST are working fine, but PUT/DELETE are not and console.log() messages in those route handlers don't even show up!!!
The response from PUT and DELETE is 404
app.js
app.use(cors())
router.js
router.delete('/', (req, res) => {
// this log statement does not show up!
console.log('request recieved')
Controller.DeleteItem(req.body.data.title).then(() => {
res.redirect('/')
}
}
console output
OPTIONS 204
DELETE 404
request
axios.delete('http://localhost:5000/', {
data: {
title: title
}
}
This was discussed outside SO : the issue was that the put and delete routes were placed inside the post route, the indentation (not appearing here) was obvious when seeing the whole code in context.

How to stop puppeteer follow redirects

Currently it seems the default behaviour of puppeteer is to follow redirects and return the DOM at the end of the chain.
How can I make the .goto() method to stop after the first redirect happened and simply return the html from that first 3xx page when i call page.content() method?
You can enable a request interception and abort additional requests if a chain of requests is identified:
await page.setRequestInterception(true);
page.on('request', request => {
if (request.isNavigationRequest() && request.redirectChain().length !== 0) {
request.abort();
} else {
request.continue();
}
});
await page.goto('https://www.example.com/');
It seems that at the moment of writing, this is not possible (at least not in the high-level API that Puppeteer provides). Check out the docs for goto here.