Redirecting based on GET request data in GitHub pages - redirect

I used to have a dynamic website, which made use of GET requests to specify pages, e.g. https://www.example.com?n=about. I have now moved over to a Jekyll site on GitHub Pages (with a custom domain), but ideally would like these old links to work.
Currently, as one would expect, such links simply return the index page. Is there any way to get the above url to redirect to https://www.example.com/about/?

There is no built-in option in GitHub pages. You cannot redirect URLs using a .htaccess file on the server.
But you can of course use client-side Javascript code:
<script>
var queryString = window.location.search;
if (queryString === "?n=about") {
window.location.replace("https://www.example.com/about/");
}
</script>
For different URLs, you'd need to store the mapping between the old and new URL, and then use a switch statement (or an if/else) to perform the redirect.
<script>
var queryString = window.location.search;
var mapping = {
"?n=about": "https://www.example.com/about/",
"?n=home": "https://www.example.com/home/",
"?n=test": "https://www.example.com/test/"
};
switch (queryString) {
case "?n=about":
window.location.replace(mapping["?n=about"]);
break;
case "?n=home":
window.location.replace(mapping["?n=home"]);
break;
case "?n=test":
window.location.replace(mapping["?n=test"]);
break;
}
</script>
Learn more about the location.search property.

Related

Dynamic Links from a CMS - Error: "redirect" can not be returned from getStaticProps during prerendering

I have a Next JS app connected to a CMS and hosted on Vercel - all links are dynamic and the pages are created by the content authors.
I am trying to create dynamic redirects that will force URLs to adhere to formats that are better for SEO. For example:
Enforce lowercase URLs
Replace spaces with dashes
Remove trailing slashes
For example, /test/Author Name/ would redirect to /test/author-name
Since I need to trigger a 301 redirect for these wrong URLs, the only way to do this with Next JS from what I have found is to return a Redirect from getStaticProps, this is what I have so far:
export const getStaticProps: GetStaticProps = async (context) => {
let requestedUrl = '/';
if (context?.params?.path) {
requestedUrl = '/' + (context?.params?.path as string[]).join('/');
}
//check for URLs with uppercases, spaces, etc. and clean them up
let modifiedUrl = requestedUrl;
modifiedUrl = modifiedUrl.trim().toLowerCase().replace(/\s\s+/g, ' ').replace(/\s/g, '-');
if (modifiedUrl != requestedUrl) {
return {
redirect: {
destination: modifiedUrl,
permanent: true,
},
};
}
This works wonderfully well running locally and connected to the CMS - everything is working as it should and all "faulty" URLs are corrected with the correct response code.
Sadly, this does not work on build, I have spent so much time so far trying to find an alternative, but no matter what I do, the build on Vercel fails with the error:
"redirect" can not be returned from getStaticProps during prerendering
The next best potential solution is to use Middleware, but that requires v.12 at least. Due to limitations from the CMS connector, we are forced to use Node v.11 :(
The alternative that I have built is to use router.push on the client side, but this... just looks terrible. The page loads, returns a 200, and then loads again with the corrected URL. Not good for the user's experience.
Any advice or suggestions? I am baffled that something this simple is this complicated with Next JS!
I resolved the issue... it looks like redirects on statically generated pages are not possible unfortunately. I removed getStaticProps and getStaticPaths, and added getServerSideProps instead. The redirects are now working correctly, but the site is not as fast as we are losing out on SSG.

Show a popup on redirect from old to new domain

I need to show a popup when the old domain is redirected to new domain in the nuxt js.
I have modified the . htaccess file and have a modal in the index.vue.
mounted() {
const modal = document.getElementById('modal')
if (document.referrer.indexOf('https://olddomain.com') > -1) {
alert('Previous domain redirected')
modal.style.display = 'block'
}
}
But there is no popup displayed. Is there a better way to do this using nuxt.
You can try the following:
Create a middleware in middleware/popupCheck.js name is up to you..
when you are creating middleware in Nuxt you should export default function, like this:
export default function(context) {
if (context.req.headers['your-custom-header']) {
// Use vuex store to dispatch an action to show a popup or set a cookie
// to listen to. Here the logic should be defined by the implementation.
}
}
The point here is to listen for a header in the request, could be a cookie also, that you have to send from your old site for every request, so make sure it's not something generic, but instead something that you cannot hit easily by mistake..
After you create your middleware you can use it on pages or layouts views, and you should add it in the default object you export:
export default {
middleware: 'popupCheck',
}
Without importing the middleware you just call it by name, this could also be an array if you wish to add multiple middlewares, and the order in that array is important.
There might be a better way to solve this, but this is the first one that came to my mind..

issue capturing the hashed URI parameters in Coldfusion [duplicate]

I have such url - http://www.coolsite.com/daily-plan/#id=1
What the easiest way to parse that string and read a hash value (the value after #id=)?
Thank you
On client side (i.e. from JavaScript) you can check window.location.hash to get hash. On server side, general answer is 'it is impossible' since hash is not sent in request to server.
Upd: I maybe misunderstood the question. My answer is about how to get hash part of url either in browser or in server side code during request processing, not about string processing.
Upd2: Answer to comment here because it doesn't fit in comment.
How does it work when user clicks on your navigational links?
I assume hash is changed and corresponding content is downloaded via AJAX request from web service or REST.
For example if your user has URL www.example.com in his browser and this page shows a list of product categories. User clicks one category and URL changes to www.example.com/#id=5 and products from that category(with ID=5) are downloaded via AJAX and shown on the page. No postback, only partial page refresh.
Is this close to your scenario?
Now you want user to paste/enter www.example.com/#id=5 directly in the browser address bar and go directly to list of products in that category.
But /#id=5 is not sent to server with request by the browser, so there is no way to get that value on server side, and you can do nothing about it since it is the browser decided not to send this data and you don't have it on server side.
In our project we use solution when server returns only common page code/html, i.e. header, footer, without main/center part of the page. Then there is a JavaScript code which executes right after this common HTML loaded. It takes window.location.hash and sends it to web service via AJAX and web service returns content (HTML) for the main part of the page.
new URI("http://.../abc#xyz").getFragment();
See the Javadocs for URI
Here is how to capture anchor links. Works across all web frameworks.
I'll use an example scenario to illustrate: let's say we need to capture a deep URL http://server.com/#/xyz requested by an unauthenticated user so that they can be redirected to that deep URL post-login.
The unauthenticated user requests http://server.com/#/xyz (everything from the '#' onwards is not sent to the server).
All the server knows is that the user wants http://server.com/ and that they are unauthenticated. Server redirects the user to a login form.
Here's the clever bit: the client is still waiting on their original request so if the server includes a hidden element in the login form with some JS that references window.location.href, it can capture the full URL of the original request complete with the anchor portion:
<form action="/login" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/><br/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<!-- XXXXXXXXX CLEVER BIT XXXXXXXXXX-->
<script>
document.write('<input type="hidden" name="from" value="'+document.location.href+'"/>');
</script>
<!-- XXXXXXXXXX-->
<div>
<input class="submit-button" type="submit" value="Submit"/>
</div>
</form>
The user authenticates themself and the original URL is sent with the POST. The server can then relay the user to the original deep URL.
String url = " http://www.coolsite.com/daily-plan/#id=1";
int sharpPos = url.indexOf('#');
String q = null;
if (sharpPos >= 0) {
q = url.substring(sharpPos);
}
Surely you can use various methods of string manipulation including regular expressions.
But actually your example is strange. Typically parameters of URL are passed after question mark. In this case you can just use standard class URL:
String q = new URL(" http://www.coolsite.com/daily-plan?id=1").getQuery();
what you are using to do this ?
If you are using jsp or servlet following will be useful to you
if (request.getParameter("#id") == null) {
out.println("Please enter your name.");
} else {
out.println("Hello <b>"+request.getParameter(i)+"</b>!");
}
If you are using javascript for it following function will be useful to you
function getURLParameters()
{
var sURL = window.document.URL.toString();
if (sURL.indexOf("?") > 0)
{
var arrParams = sURL.split("?");
var arrURLParams = arrParams[1].split("&");
var arrParamNames = new Array(arrURLParams.length);
var arrParamValues = new Array(arrURLParams.length);
var i = 0;
for (i=0;i<arrURLParams.length;i++)
{
var sParam = arrURLParams[i].split("=");
arrParamNames[i] = sParam[0];
if (sParam[1] != "")
arrParamValues[i] = unescape(sParam[1]);
else
arrParamValues[i] = "No Value";
}
for (i=0;i<arrURLParams.length;i++)
{
alert(arrParamNames[i]+" = "+ arrParamValues[i]);
}
}
else
{
alert("No parameters.");
}
}
REPLACE the '#' with '?' when parsing the url. Check the code below
String url = "http://www.coolsite.com/daily-plan/#id=1";
String urlNew = url.replace("#", "?");
String id = Uri.parse(urlNew).getQueryParameter("id");
If you URL will the same as you write and doesn't contains anythins else then whis code on Java will help you
String val = "http://www.coolsite.com/daily-plan/#id=1";
System.out.println(val.split("#id")[1]);
Don't forget check to null value.
P.S. If you use servlet you can get this parameter from request.getAttribute("id").
With best regards,
Psycho
if your url get from OAuth callback,then you can't!
because the full url won't send to service because of hash(#)

CSRFGuard - request token does not match session token

I am trying to incorporate the CSRFGuard library in order to rectify some CSRF vulnerabilties in an application. However after configuring as specified here I am now getting the below messages in the log, when I navigate the application:
WARNING: potential cross-site request forgery (CSRF) attack thwarted (user:<anonymous>, ip:169.xx.x.xxx, uri:/myapp/MyAction, error:request token does not match session token)
Through including the:
<script src="/sui/JavaScriptServlet"></script>
On my main.jsp page the links have all been built incorporating the CSRFGuard token, e.g.
......./myapp/MyAction?CSRFTOKEN=BNY8-3H84-6SRR-RJXM-KMCH-KLLD-1W45-M18N
So I am unable to understand what I'm doing wrong that could cause the links to pass a token other than the expected value.
Please let me know if any additional information would make it easier to understand.
In case anyone stumbles across a similar issue:
Turned out that accessing the app using IE wasn't passing a token to an AJAX call, this would in turn result in the tokens being refreshed but the links in the already rendered page remained, causing the mismatch when clicked.
Found out the issue by building CSRFGuard myself from source and adding extra logging.
The primefaces commandlink and commandbutton seem to cause the csrfguard javascript to malfunction, if you have use these two component with ajax set to true (which is the default), it can prevent the token being injected after the ajax call
One of the possible fixes is to change the following 2 lines in Owasp.CsrfGuard.js file.
Change
function injectTokenForm(form, tokenName, tokenValue, pageTokens) {
var action = form.attribute("action");
To
function injectTokenForm(form, tokenName, tokenValue, pageTokens) {
var action = form.attributes["action"].value;
AND
Change
function injectTokenAttribute(element, attr, tokenName, tokenValue, pageTokens) {
location = element.getAttribute(attr);
To
function injectTokenAttribute(element, attr, tokenName, tokenValue, pageTokens) {
var location = null;
if (attr == "action") {
location = element.attributes[attr].value;
} else {
location = element.getAttribute(attr);
}

How can I redirect an address starting with #!

I have a new wordpress site instead of my old Wix one.
in the old one there were page addresses like http://example.com/#!contact/ct07/ in the new one this page resides under http://example.com/contact
I've tried 3 redirections plugins but none works (Redirection, redirection editor, quick 301 redirect).
I have no access to the .htaccess file
On redirection it seems like the engine does not see the URL.
Any manageable idea besides JS ? I don't want to miss google juice
Browsers don't send the part after # to the server, so the server don't know about this part and won't be able to do the redirect.
So you have to do the redirection in javascript:
if (/^#contact\//.test(document.location.hash)) {
document.location = '/contact';
}
For SEO purpose, you may want to handle the _escaped_fragment_ parameter too
I had this problem a few weeks ago.
PHP does not get anything after hash tag, so it is not possible to parse request url and get hash. But JavaScript can.
Below you find my solution for WordPress redirects by hashtag #! :
(You should put this code in functions.php of your active theme):
function themee_hash_redirects() {
?>
<script type="text/javascript">
function themee_hashtag_redirect( hashtag, url) {
var locationHash = document.location.hash;
if ( locationHash.match(/#!/img) ) {
if ( hashtag == locationHash ) {
document.location.href = url;
}
}
}
// Examples how to use themee_hashtag_redirect
themee_hashtag_redirect('#!contact', '/qqq/');
themee_hashtag_redirect('#!zzz', '/aaa/');
</script>
<?php
}
add_action('wp_footer', 'themee_hash_redirects');