Is it possible to open an html file, have it send some signal to a server-side application to query data from a mysql db and then return that data to that original html file? So instead of having some php or js program spit out an html file, can i create an 'index.html' file that when i click on, will display contents of my db? Thanks
If the question is limited to using only HTML, then this is not possible.
If you mean only using a static HTML page (allowing inline JavaScript), then there are lots of ways you could do what you want.
You could use client side JavaScript, served in a static page removing the need to run a backend like Node JS or some other kind of non static web server.
Something like this for your static HTML file:
<html>
<head>
<title>Using Fetch</title>
</head>
<body>
<script>
// Fetch your information here using client side JavaScript
// Do something
</script>
</body>
</html>
Your server side application can expose an endpoint that outputs some JSON, we will use the endpoint https://example.com/api/ and fetch it using Fetch API:
let url = 'https://example.com/api/';
fetch(url)
.then(res => res.json())
.then((data) => {
// Your data is in the variable 'data', do something with it
})
.catch(err => { throw err });
All together your HTML file could look something like this:
<html>
<head>
<title>Using Fetch</title>
</head>
<body>
<p id="data"></p>
<script>
let url = 'https://example.com/api/';
fetch(url)
.then(res => res.json())
.then((data) => {
document.getElementById("data").innerHTML = data;
})
.catch(err => { throw err });
</script>
</body>
</html>
That code is a basic example of getting some data from an endpoint and setting a paragraph on your page to show that information.
Related
Im writing an PWA in Svelte with Routify and im trying to save notes (containing id, title and a body) in a local json file.
Ive been following this code from Svelte REPL (Svelte POST example), but they use an web URL. When trying to use a direct link i get a 404, even tho the path is correct.
<script>
let foo = 'title'
let bar = 'body'
let result = null
async function doPost () {
const res = await fetch('https://httpbin.org/post', {
method: 'POST',
body: JSON.stringify({
foo,
bar
})
})
const json = await res.json()
result = JSON.stringify(json)
}
</script>
<input bind:value={foo} />
<input bind:value={bar} />
<button type="button" on:click={doPost}>
<p>Post it.</p>
</button>
<p>Result:</p>
<pre>
{result}
</pre>
I installed a json server plugin, which kinda worked, but i want to store the data as a local file.
Is it possible to write, using POST to a local json file without using any server?
Is it possible to use relative path when using fetch? Or should i use something else?
Generally, you don't POST data anywhere else but to a server. Having said that, if you absolutely want to save your data using POST, you can add a serviceworker to your app that intercepts the fetch() request and then saves the data in cache, indexeddb, localstorage or something like this. But having that serviceworker in between just for that is a bit silly, you should rather store the data directly in cache, indexeddb or localstorage.
Example for localstorage:
const data = { someKey: { someOtherKey: 'some value' } };
localStorage.setItem('myData', JSON.stringify(data));
Be aware though that, no matter which kind of storage you're using, they all might be wiped out if the user decides to clear browser data or if the browser cleans up by itself due to storage shortage.
as the Question title. Is there any way to fetch local json data without putting the json file under public or src folder in react? so what I need is as below image (red circle):
and my fetch code is like below (it didn't get anything):
const [movies, setMovies] = useState([]);
useEffect(() => {
fetch(`../server/testData.json`)
.then((res) => res.json())
.then((data) => setMovies(data))
.catch((err) => err);
}, []);
the target that I would like to achive is like below:
If I put the json file under public folder and change fetch code to fetch("./testData.json") or put the file under src folder and import the json file normaly without using fetch function/api and map ex. import data from "./testData.json" then data.map(value => value) I achieved as the above image, but the problem is I wanted to fetch the json file from outside of both folder (public & src). Is there any way to do that?
If you want to mock fetch for development and testing take a look at MSW
It was built for exactly that use case.
If not just import the json without using fetch.
I want to insert a script in my application's <head>, but the src attribute of that script depends on a runtime environment variable in my hosting server (OpenShift).
So if process.env.ENVIRONMENT === "test", I want to insert <script src="www.someurl.com/test.js" /> into the application's <head> and if it's "prod" then something else.
I have all these src values stored in a json file that I don't want to show up in the client. How do I make sure the client can receive the correct src from the server without having access to the json file with all the environment's endpoints?
Express:
With Express I used to just inject the src value into the window object at runtime before serving index.html but I'm not sure how to do it in Next.js
Code: Here's what I tried
// _app.tsx
...
<Head>
<script src={getScript()} type="text/javascript" />
</Head>
...
where getScript() is a function in <root>/scripts
export function getScripts() {
if (process.env.ENVIRONMENT === "test") {
return scriptSrc.test;
} else if (process.env.ENVIRONMENT === "prod") {
return scriptSrc.prod;
}
}
You can use getServerSideProps to pass properties from the server to the client. Since the server has access to any runtime env variables, you can simply pass your variable to the client. In the render function use the env variable to decide which script to inject into the header.
This simple page showcases how to pass an env variable:
export const getServerSideProps = async () => {
return {
props: {
my_env: process.env.RUNTIME_ENV || 'default',
}
}
}
export default function MyPage(props) {
return <div>{props.my_env}</div>
}
npm run dev renders "default" while RUNTIME_ENV="foobar" npm run dev renders "foobar".
I couldn't find a way to populate the data in _app.js at fetch time from the server since that file doesn't support getServerSideProps so I took the long road and did it client side instead.
Step 1:
Create an api route that returns back a JSON object with all the data you need in all the pages of the application. All process.env references work inside the pages/api folder since that code always runs on the server.
export default (
req: NextApiRequest,
res: NextApiResponse<StartResponseType>
) => {
res.status(200).json(getScripts(process.env.ENVIRONMENT.trim()));
};
Step 2:
Now we need an efficient way to cache this response on the client since we don't want to keep fetching it for every page. I used react-query for this.
export function queryStart() {
return useQuery<StartResponseType>("start", getStart, {
staleTime: Infinity,
});
}
Step 3:
We can't use the hook created above in _app.js until we wrap our App component in QueryClientProvider, so we need to create a Higher Order Component since there's no component that wraps App.
export const withQueryCache = (Page: any) => (props: any) => (
<QueryCacheProvider>
<Page {...props} />
</QueryCacheProvider>
);
Step 4:
Now we just need to put it all together and add a loading state to the App so it only initiates the application once the initial data has been fetched.
// _app.tsx
function App({ Component, pageProps }: AppProps) {
const startQuery = queryStart();
if (startQuery.isSuccess) {
return (
<>
<Head>
<script src={startQuery.data.scriptEndpoint} type="text/javascript" />
</Head>
<Component {...pageProps} />
</>
);
} else return <>Loading</>;
}
export default withQueryCache(App);
However, I would've still preferred for a way to just inject data from the server at fetch time. That would've been possible if _app.js file supported getServerSideProps. But until that's supported, this seems to be the best workaround.
I'm using Node. On server side, I got requests from clients. Before sending response to the client, I'm fetching data from other web sites so I'm creating a request object using request npm module.
Basically I have something like this :
request(url, (req,resp) => {...});
The problem is with some pages it's dynamic. Think about something like facebook, when you scroll down the page with your mouse => new data is coming and the HTML code is becoming bigger and bigger.
The problem with the HTML data I got back from resp object in mycallback function is that it only has very little data.
With a browser I can get more data by scrolling down the page but is it possible to get all data programatically ?
Thank you ;)
You can try:
request(url, (req,resp) => {...})
.on('complete', (data) => {
console.log(data.body);
});
Or
let bufferedData = '';
on('data', (data) => {
bufferedData += data.toString();
})
Can you include JSON-like data in a response using connect/express?
When users hit '/' i want to respond with all the assets but also if they are logged in I'd like to send a user object with this payload. Is this possible or do I need to make another request afterwards from the client??
You could use Express' dynamicHelpers, or perhaps helpers: http://expressjs.com/guide.html#app.dynamichelpers()
Something like this, in your app:
app.dynamicHelpers({
user: function(req, res) {
return req.session.user;
}
});
In your view:
<head>
<!-- ... -->
<script>
var user = <%- JSON.stringify(user) %>;
</script>
<!-- ... -->
Or, you could take a look at the Express expose module, which is made for this purpose!