I have a NextJS application that sometimes isn't working as expected.
When I'm with a slow connection and the first load time of the site is bigger than normal, when I try to login into application, the default behavior of HTML form is executed and the credentials that I inserted are shown on the URL, even though I've a event.preventDefault() in the submit function and I'm not using GET.
I've tried to improve the performance of the app and reduce the first time load of the pages, but, if the user can make the loading time slow, it can be exploitable.
I just want to prevent that the credentials be shown on URL.
It can be replaced with any type of another error.
Here is my code:
async function handleLogin(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
setIsLoadingLogin(true);
setError('');
const captchaValue = await captchaRef.current?.executeAsync();
if (!captchaValue) {
setError('Erro de captcha. Tente novamente mais tarde.');
return setIsLoadingLogin(false);
}
try {
const { access, refresh } = await loginService({
email,
password,
captcha_value: captchaValue,
});
setCookie(undefined, cookieNames.userAccessToken, access);
setCookie(undefined, cookieNames.userRefreshToken, refresh);
await router.push('/home');
} catch (error: any) {
if (error.response.status === 500) return setError('Erro no servidor.');
if (error.response.data.detail) return setError(error.response.data.detail);
} finally {
setIsLoadingLogin(false);
setPassword('');
captchaRef.current?.reset();
}
}
<form onSubmit={handleLogin}>
...
</form>
Since you say that it's cause of slow connection - means JS is not yet downloaded while you submit your form.
I see few solutions:
Add method="POST" to your form - still submit is executed not via JS, but via HTML form
Initially hide your form or make submit button disabled. Then when JS is loaded enable form
use btoa() and atob() js functions to encrypt and decrypt
Related
I have a button Submit when clicked performs some operation calling an API. Post click, the button is disabled or basically the initial state of the button and the operation is changed.
I have two or multiple browser tabs which shows same screen of Submit. If in any one of the tab, the Submit operation is performed, the other tabs should show the updated version. The other tabs should show the disabled version and should not show the initial state.
How do I achieve this? I am using React, JS
#1 Data duplication MUST be restricted at the server side.
I would recommend some cache like node-cache. Node-cache will having scalability issues, so better to go with redis. (The logic should be smt. like: If the form has submited with the user_id, or with form_id, you can create a cache for that, and if you proceed it, store it in the db, other case throws an error. On the other browser you must validate before the submit if the unique_id neither in the cache nor in the db. If exists, you can throws an error in the nr.2 browser.
#2 If you want to disable the button, you have to use websockets
If you're looking for a client-only solution, here is a great article about sharing state between browser tabs. The limitation is that it won't work on different browsers/machines.
The best way to handle this from a UI/UX perspective is to use validation. If User A clicks submit, then User B clicks submit from a different browser or tab, an error should be displayed to User B indicating that "This action has already taken place".
That being said, what you are trying to achieve is possible.
One way is by using a WebSocket. A WebSocket is a persistent connection between the client and server, that allows bi-directional communication.
The page with the submit button in your React app would be a "subscriber" to some websocket channel. When the submit button is clicked for the first time(it doesn't matter from where), a message can be "published" from a WebSocket server to ALL subscribers, regardless of the browser or tab being used.
Basically, you would add an onMessage handler in your React app where you can disable the submit button when a specific message is received.
I don't know what tech you are using on the server side, but for a WebSocket server, there are many options out there. For the React app, there is react-websocket which is straight-forward to use.
you can do it in client-side
const Form = () => {
const [buttonDisabled, setButtonDisable] = useState(false);
// first tab fire
const onSubmit = () => {
.
.
.
localStorage.setItem("formSubmited", "true");
};
useEffect(() => {
const disableButton = (e) => {
if (e.storageArea.formSubmited) {
setButtonDisable(true);
}
};
// second tab fire
window.addEventListener("storage", disableButton);
return () => {
window.removeEventListener("storage", disableButton);
};
}, []);
.
.
.
};
I have implemented Google Script for sending an email to the specific user.
I reffered the code from here.
My problem statement is as follows :
Instead of sending the response to the user I want to navigate the user to specific website say https://stackoverflow.com what changes I need to do in my code.
Here is my code
var TO_ADDRESS = "ad.stack69#gmail.com";
function doPost(e) {
try {
Logger.log(e);
MailApp.sendEmail(TO_ADDRESS, "Contact Form Submitted", JSON
.stringify(e.parameters));
return HtmlService
.createHtmlOutput("https://stackoverflow.com");
} catch (error) {
Logger.log(error);
return ContentService.createTextOutput(JSON.stringify({
"result" : "error",
"error" : e
})).setMimeType(ContentService.MimeType.JSON);
}
}
What I tried to do is to navigate on https://stackoverflow.com but instead of navigation it's printing on browser as a response
Please let me know what changes I need to do in my code.
There is no built in why of doing it yet as far as I know. This is the trick I've been using for a while:
function doGet(){
return HtmlService.createHtmlOutput("<script>window.top.location.href = 'https://stackoverflow.com'</script>");
}
It does the trick.
I'm trying to build a single ReactJs form-component (writing in TypeScript targeting ES6) which I will use for all forms in my web-application.
In order to handle errors when a form is posted, I need to check for errors in case there are any.
This is my handleSubmit method:
private handleSubmit = (ev: React.FormEvent<HTMLFormElement>): void => {
var theForm = ev.target as HTMLFormElement;
const formData = new FormData(theForm);
fetch(theForm.action, { method: theForm.method, body: formData })
.then(response => {
if (!response.ok)
throw Error(response.statusText);
return response;
})
.catch(reason => console.log(reason));
}
The action I am currently working on is a simple POST-action (example):
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> Login(RequestAccountLoginPost request)
{
throw new ApplicationException("The application crashed in a way nobody expected. Sorry about that...");
}
However, when submitting the form, I always end up with the ASP.net standard error-page.
How I can stop this behavior and stay on the page the form is on showing some errors e.g. There was an internal server-error. Write an e-mail to help#me.please which helps the user indentifying that something went wrong?
Later I want to implement some handling in case server-side validation fails (but client-side not) so I can show the user: Look. This value is wrong. Please fix.. Therefore I do need to stay on the same page.
I'm new to using fetch-api. Maybe this is not the best choosen option for this?
You need to prevent the normal submission of the form and handle everything in JS, otherwise your page will post by default the data to your server.
private handleSubmit = (ev: React.FormEvent<HTMLFormElement>): void => {
var theForm = ev.target as HTMLFormElement;
ev.preventDefault()
// ... your code
From MDN: The Event interface's preventDefault() method tells the user
agent that if the event does not get explicitly handled, its default
action should not be taken as it normally would be.
I'm using Firebase perhaps slightly unconventionally -for simple form submission. Submission of my website's contact form simply results in:
ref.push({name:'dr foo', email:'1#2.com', message:'bar'}, myCallback);
The Firebase is hooked up to Zapier to send the site owner an email. All works well, but I'd like to be able to handle the user loosing their connection. When Firebase can't reach the server I'd like to display: "Please check your connection", or a similar message when the user hits the send button. The "Thanks, we'll be in touch"-type message should only be displayed on a successful write.
At first I tried including an if (error) branch in the callback, but of course disconnection is not something that Firebase considers an error as it "catches up" when it can.
I also tried the code in the docs which monitors .info/connected. While this wouldn't display a message on a form submission attempt, I was thinking I could instead display a warning if disconnected. The sample worked intermittently (Chrome 39, Firefox 30, Linux Mint), but the lag between disconnection and the event firing means it's probably not suitable for this case.
Is what I'm trying to do possible?
It indeed seems that the .info/connected values only changes once some other data transfer occurs (and fails).
The only way I can come up with is by using the transaction mechanism with applyLocally set to false. E.g.
function testOnlineStatus() {
var ref = new Firebase('https://your.firebaseio.com/');
ref.child('globalcounter').transaction(function(count) {
return (count || 0) + 1;
}, function(error, committed, snapshot) {
if (error) {
alert('Are you offline?');
}
}, false /* force roundtrip to server */);
}
setInterval(testOnlineStatus, 2000);
This one triggered for me after about 15 seconds.
I am creating a Facebook Canvas application, and I am following more or less the demo app.
As in the demo, I can get the user data from the signed_request which is POSTed to my site on the first page load. Moreover, as suggested in the demo, I use the following snippet to reload the page on user changes:
var Config;
function facebookInit(config) {
Config = config;
FB.init({...});
FB.Event.subscribe('auth.sessionChange', handleSessionChange);
...
}
function handleSessionChange(response) {
if ((Config.userIdOnServer && !response.session) ||
Config.userIdOnServer != response.session.uid) {
goHome();
}
}
function goHome() {
top.location = 'http://apps.facebook.com/' + Config.canvasName + '/';
}
Here Config is an object which is populated with info from the server.
The problem appears when the user navigates the application using a link. If I use AJAX, the page is not actually reloaded and everything works fine. But if I use a standard link, the user comes to another page of my application with a standard GET request. In this case, I do not know how to get the info about the user, so Config.userIdOnServer is undefined and a page reload is triggered.
Of course I can avoid this by removing the call to handleSessionChange, or by making a one-page app with only AJAX links, but I feel I am missing something basic about the Facebook flow.
My fault, I had problems in retrieving the cookie with the user identity for subsequent requests.