Can't set Cookies in browser even though header is present - javascript

I was working on adding cookies to my project, full source here, but I ran into an issue where I can't set the cookies properly. I made a new api route that just creates a cookie and sends an object to the client.
server/routes/todo.routes.js
router.get('/todos', (req, res) => {
res.cookie('mycookie', 'a_value')
return res.send([{id:'1',isCompleted:false,text:'something'}])
})
If I call this api route directly, the browser renders the object and the cookie is set. The problem is when I call this api via AJAX from a rendered page, I still get the same response, but cookies aren't set. NOTE: I export the router and do app.use('/api', exported_object_here), so the URL is /api/todos.
shared/actions/todo.actions.js
export const getTodos = () => {
return (dispatch) => {
return fetch('/api/todos')
.then(response => response.json())
.then(todo => dispatch(_receiveTodos(todo)))
.catch(err => dispatch(_errorHandler(err)));
}
};
I have no idea why the browser would act differently in that situation, especially with something so simple. Do you all have any clue what could cause this?

You need to set withCredentials on your XHR request (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)

Related

Axios/Backend in React stops working after a while with no error

My React App takes user input from frontend and send it to backend via Axios where the info will be used to search through MongoDB. My App works fine for a few input, like around 5-6, then it will stop working with no error and I have no idea what is wrong and how to fix it.
Here is an example of my problem, this useEffect will happen when page load and take param from the url and send it to backend (the param change depends on what link the user clicks on). It will then send the information to backend via axios and the Info is used to search through MongoDB and will dynamically generate the page's text. After the user clicks on around 5 different links tho, this will stop working and the page generated will be stuck on the last page it was generated dynamically although the params in the url still change. I added console.log to see if useEffect was activating or not, and everytime I click on a Link, the console.log will work when the page load. Any lead will help, thanks!
frontend runs on port 3000 and backend runs on 3001
useEffect(() => {
const idInfo = {id};
axios.post('http://localhost:3001/info', idInfo);
console.log("testing")
}, [])
useEffect(() => {
fetch("/info").then(res => {
if(res.ok) {
return res.json();
}
}).then(jsonRes => setGetId(jsonRes))}, [])
This is the backend
router.route("/info").post((req, res) => {
console.log(req.body)
const idInfo = req.body.id;
console.log(idInfo);
current_id = idInfo;
})
router.route("/info").get((req,res) => {
Disease.find({_id: current_id})
.then(foundId => res.json(foundId))
})
This way, when you fetch('/api/info') in development, the development server will recognize that it’s not a static asset, and will proxy your request to http://localhost:3001/api/info as a fallback. The development server will only attempt to send requests without text/html in its Accept header to the proxy.
Conveniently, this avoids CORS issues and error messages like this in development:
Fetch API cannot load http://localhost:3001/api/info. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
https://create-react-app.dev/docs/proxying-api-requests-in-development/
src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:3001',
changeOrigin: true,
})
);
};
useEffect(() => {
const idInfo = {id};
axios.post('/api/info', idInfo);
console.log("testing")
}, [])
useEffect(() => {
fetch("/api/info").then(res => {
if(res.ok) {
return res.json();
}
}).then(jsonRes => setGetId(jsonRes))}, [])

React native fetch data

I have a problem with fetch data. My friend creates Rest Api.
There is my fun:
const AnyCors = `https://cors-anywhere.herokuapp.com/`;
const urlAllBus = `http://207.185.72.111:15430/stops?size=15`;
fetchBusStop = () => {
return new Promise((resolve, rejects) => {
fetch(AnyCors+urlAllBus)
.then((result) => {
if (!result.ok) throw result.json();
return result.json();
})
.then((result) => {
console.log(result);
resolve(result);
})
.catch((error) =>
error.then((body) => {
console.log('Bad', body);
rejects(body);
}),
);
});
};
I create an app with react-native. When I use only urlAllBus my virtual machine work fine. The problem is with a physical machine. When I try using my fun with urlAllbus in chrome I get a problem with CORS so I used AnyCors+urlAllBus and everything works fine. But in the virtual and physical machine there solutions not work. I don't know what I should do
You friend's API should accept CORS by adding a Access-Control-Allow-Origin: * header to its responses to allow any website to access it. They can also limit access to a specific site by setting the header to the base URL of such site, like Access-Control-Allow-Origin: http://example.com.
If the API is express-based, I hightly recommend the cors package for the job, as it makes it a single-line change.
Otherwise, tell them to give this MDN page a read for more information about CORS :)

How to properly prefetch a json endpoint in Chrome?

I am trying to speed up the network critical path on a website, and find out about the great <link rel=preload. So I try to anticipate the call that my single page application do as soon as the JS kicks in, I have put in my index.html
<link rel="preload" href="/api/searchItems" as="fetch" />
Then as the JS starts I make the same call with the help of the axios library:
await axios.get(`/api/searchItems`, { params: queryParams });
I would expect to see the call of Axios returning instantly the preloaded JSON file but instead, I see this:
As you can see the same call is loaded twice.
What I am doing wrong?
EDIT: I have added cache-control: public and nothing changes.
EDIT2: I also tried this code instead of axios:
let data = await fetch('/api/searchItems')
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('HTTP error ' + response.status);
})
.catch(() => {
data = null; // Just clear it and if it errors again when
// you make the call later, handle it then
});
And nothing change
Three options for you:
It looks like your response has headers making it uncacheable for some reason. You may be able to fix it so it's cacheable.
Use a service worker.
Another approach, if this is really critical path, is to have some inline JavaScript that actually does the call and modify the code that will do the call later to look to see if the previous result is available, like this:
let firstLoad = fetch("/api/searchItems")
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error("HTTP error " + response.status);
})
.catch(() => {
firstLoad = null; // Just clear it and if it errors again when
// you make the call later, handle it then
});
(I'm using fetch there because you may want to do it before you've loaded axios.)
Then in the code that wants this data:
(firstLoad || axios.get("/api/searchItems").then(response => response.data))
.then(/*...*/)
.catch(/*...*/);
firstLoad = null;
If the content requires revalidation (and you're using no-cache, so it does¹), #2 and #3 have the advantage of not requiring a second request to the server.
¹ From MDN:
no-cache
The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it...
(my emphasis)

Redirect/ Routing issues in React and Express

I am creating a flight search app that makes external api calls. The data will be reorganized and returned in search results component.
On submit, the data is sent to express and takes about 10 seconds or more to complete all the api calls.
I think I need a loader at some point for during the delay of api calls, but also I am unsure of how to send/render the data.
As it stands, I have two pages home.js- '/' where i make the search and is sent to the server side, and prices.js- '/search' which when loaded fetches the data from the json file. but i do not have them connected
Both files work but I need to connect them. When I press submit, the user inputs are sent to server and the api calls are made but in order to see the results i have to manually refresh localhost:3000/search.
In express app after all the api calls, I tried res.redirect method, however the error given was setting the headers after sent to the client.
In react, I tried after submitting, to redirect to the search page. However I could not get it to redirect and also as soon as the /search page is called, it fetches the data from the file. This will happen before the api has finished writing to file and therefore the previous search results will render.
--in app.js
setTimeout(() => {
Promise.all([promise, promise2]).then(values => {
return res.redirect('http://localhost:3000/search');
});
}, 25000);
I had to wrap the api calls in promises so it will only redirect after all is written to file.
(in react prices.js)
componentDidMount() {
fetch('/search')
.then(res => {
return res.json()
})
.then(res => {
console.log(res.toString());
this.setState({flightData: res});
})
.catch(error => console.log(error));
}
home.js
home.js
```
onChange = (e) => {
this.setState({
originOne: e.target.value, originTwo: e.target.value});
};
onSubmit = (e) => {
e.preventDefault();
const { originOne, originTwo ,redirectToResult} = this.state;
};
```
app.js - I have all the functions calling each other in a waterfall style ( probably not the best way I know)
app.post('/', function getOrigins(req,res) {
var OrigOne;
var OrigTwo;
....
function IataCodeSearchOrg1(res, OrigOne, OrigTwo) {
...
findPrices(res,A,B)
}
function findPrices(res, A, B) {
promise = new Promise(function (resolve) {
...
}
}
All the methods are called within eachother. The api calls are in a loop and after each iteration they are written to the json file.
All these functions are in the app.post method and i tried to res.redirect but it did not work.
EDIT:
You can't redirect server-side from an XHR request. You would need to redirect client-side.
e.g.
componentDidMount() {
fetch('/search')
.then(res => res.json())
...
.then(() => window.location = '/myredirecturl')
}

How to make server side requests (API) with a catch-all React app?

I'm relatively new to react/redux and I've encountered a problem.
Say for example I want to search for an item.
export default function getSearchItems(itemName) {
return dispatch => {
// Show that it is requesting, will be updated after.
dispatch(requestItems(itemName));
// URL todo.
return fetch('/search')
.then(
response => response.json(),
error => dispatch(requestItemsFailure(itemName))
).then(
json => dispatch(requestItemsSuccess(itemName, json))
);
};
}
Here I've made a request to the url /search. But because I've opted to use React Router v4's client side routing, I did this on the server-side.
// Manage Routes
app.get('/*', function (req, res) {
res.sendFile(path.resolve(__dirname + '/../build/index.html'));
});
// Search Grab data
app.get('/search', function (req, res) {
console.log('hit');
res.status(200).json(
{item:"test"}
);
});
Since I used a "catch-all" method as described here in this stackoverflow post, I can no longer do something like "/login" and have it go to the correct component immediately.
How can I make the two work together properly?

Categories

Resources