React application failing to fetch once publicly hosted - php

can anyone help me with the following issue? This is all very new to me so I'm sorry for any incoveniences. I'm creating a ChatGPT tool which takes a text inputs from the user in the front end then passes that data into the back end which sends the user input to an open OpenAI API layer. The back end then receives a response back from the OpenAI layer and stores the text response into a text array and writes it back to the front end into a standard text area.
The website runs perfectly when it is hosted locally on localhost:3001 and port:3001. My issue stems when I deploy the website to firebase and attempt to submit a form request on another machine and different network it does not writing any text to the textarea. Below I have provided my code. I believe the issue has something to do with the localhost code in the handleSubmit function or could even be in the back end script i'm very unsure and would really appreciate any help I can get thanks to get this running publicly. Thanks for your time :)
Front End (App.js)
import React, { useState } from 'react';
import './App.css';
function App() {
const [message, setMessage] = useState('');
const [response, setResponse] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
fetch('http://localhost:3001', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({message}),
})
.then((res) => res.json())
.then((data) => setResponse(data.message));
};
return (
<body>
<div className="App">
<form onSubmit={handleSubmit}>
<div class="section"></div>
<header>
<nav>
<ul class="nav_links">
<li><a href='#'>Home</a></li>
<li><a href='#'>Pricing</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Contact</a></li>
</ul>
</nav>
<button class="login">Login</button>
</header>
<input type="text" id="topic"
value={message}
onChange={(e) => setMessage(e.target.value)}
></input>
<textarea id="textarea" value={response} />
<div> <button id="generate" type="submit">Generate</button> </div>
</form>
</div>
</body>
);
}
Back End (Index.js)
const OpenAI = require('openai');
const { Configuration, OpenAIApi } = OpenAI;
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 3001;
const configuration = new Configuration({
organization: "org-kEBxx4hVwFZ",
apiKey: "sk-jmYuTSCZvxCjidnbTpjFT3Blbk",
});
const openai = new OpenAIApi(configuration);
app.use(bodyParser.json());
app.use(cors());
app.post('/', async (req, res) => {
const { message } = req.body;
const response = await openai.createCompletion({
model: "text-davinci-003",
prompt: `${message}`,
max_tokens: 1000,
temperature: 0,
});
console.log(response.data)
if(response.data.choices[0].text){
res.json({message: response.data.choices[0].text})
}
});
app.listen(port, () => {
console.log("Listening...")
});

Since http://localhost:3001 is hardcoded into your code, even when you deploy it in production, the production website will still try to make a request to localhost:3001. To fix this, you need to dynamically set the url based on whether the code is in development or production. The recommended way to do this is using environment variables: https://create-react-app.dev/docs/adding-custom-environment-variables/, where you'd set the env variable to localhost:3001 during development and the url of the production server in production.

Related

React hook failed to call php server via ajax

I want to submit a react form making an ajax call to php server. I have used react hook but since I am new to it, I cant not figure out error actually.
function App() {
const [name, setName] = useState("");
const [result, setResult] = useState("");
const handleChange = (e) => {
setName(e.target.value);
};
const handleSumbit = (e) => {
e.preventDefault();
const form = $(e.target);
$.ajax({
type: "POST",
url: form.attr("action"),
data: form.serialize(),
success(data) {
setResult(data);
}
});
};
return (
<div>
<form
action="server.php"
method="post"
onSubmit={(event) => handleSumbit(event)}
>
<label htmlFor="name">Name: </label>
<input
type="text"
id="name"
name="name"
value={name}
onChange={(event) => handleChange(event)}
/>
<br />
<button type="submit">Submit</button>
</form>
<h1>{result}</h1>
</div>
);
}
const header4 = ReactDOM.createRoot(document.getElementById('header4')) ;
header4.render(<App />);
I have skipped the import part. The above code runs without any error but when I click the button, nothing happens.
This is my php code:
<?php
header('Access-Control-Allow-Origin: http://localhost:3000');
$user = $_POST['name'];
echo ("Hello from server: $user");
?>
I verified that your react code is working fine, and if you check in network tab in developer tools in any browser, there is a POST request going to http://localhost:3000/server.php. The reason you see nothing happening is that this url might not be what you server is listening to.
If we don't provide the absolute url, relative path causes your request to be handled by react at http://localhost:3000/server.php and it errors out as there is no resource to handle it.
To fix the issue, change form action attribute to:
http://<serverhost>:<serverport>/server.php
This should work for localhost based servers. For production applications, you might consider making POST request to a server instead of form submission.
Please try and let me know if this fixes your issue.

React + Laravel + Sanctum for api token authentication(NOT cookie)

I am trying to get React and Laravel to work together using the middleware Sanctum.
I can read many examples of people trying to do this with a cookie based setup, but I am trying to use the token setup for a pure API approach. I am doing this because I want to prepare the backend for use in a mobile app where cookies are not available.
This is a part of my setup:
/backend/routes/api.php:
Route::post('/login', [ UserController::class, 'getAccessToken'] );
/frontend/store/api.js
static login( user ) {
var formData = new FormData();
formData.append('username', user.username);
formData.append('password', user.password )
formData.append('deviceName', 'browser');
return fetch(
'http://localhost:5001/api/login, {
method : 'post',
body : formData
}
);
}
My problems is that it forces a CSRF token check, when the login route is accessed.
That is even if the login route shouldn't be guarded by Sanctum.
This of course fails when I am logging in and don't yet have a token to attach to the request.
As I understand the token is only needed on accessing guarded routes after login.
I have double checked that it is accessing the right route by renaming it to something fake and getting an error.
Am I doing something wrong with the use of Sanctum or is Sanctum just not the preferred use for api tokens? Should I maybe look into JWT instead?
Thank you in advance for your help. <3
Please, check this url, I was able to make it work thanks to this tutorial.
https://laravel-news.com/using-sanctum-to-authenticate-a-react-spa
here is my LoginForm.jsx
import React from "react";
import apiClient from "./services/apiClient";
const LoginForm = (props) => {
const [email, setEmail] = React.useState("");
const [password, setPassword] = React.useState("");
const handleSubmit = (e) => {
e.preventDefault();
apiClient.get("/sanctum/csrf-cookie").then((response) => {
apiClient
.post("/api/sanctum-token", {
email: email,
password: password,
device_name: "React v0.1",
})
.then((response) => {
console.log(response);
});
});
};
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<input
type="password"
name="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
<button type="submit">Login</button>
</form>
</div>
);
};
export default LoginForm;
apiClient.js
import axios from "axios";
const apiClient = axios.create({
baseURL: "http://localhost",
withCredentials: true,
});
export default apiClient;
In:
/backend/app/Http/Kernel.php
I had added:
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
It worked when I removed that line. I had failed to understand that a SPA equals the use of cookies, because I would say that I am also working on a SPA that just uses API tokens instead.
Next issue is that I am using Doctrine instead of Eloquent, which I can now see it far from compatible with Sanctum when it comes to issuing the token. But that will be a topic for another question.
I use this tutorial https://medium.com/#suton.tamimy/basic-token-authentication-with-fresh-laravel-8-sanctum-and-reactjs-ef14eba7ce0f
default setting laravel (no setting modifications etc) with API Login output TOKEN and BEARER token type. Then in ReactJs, just use this axios setting to generate the token (no need sanctum/csrf-cookie).
axios.defaults.baseURL = '_MY_API_';
axios.post('/login', {
email: '_EMAIL_INPUT_FORM _',
password: '_PASSWORD_INPUT_FORM_'
})
.then(({ data }) => {
if(data.status==="success"){
console.log(data)
} else {
console.log("error")
}
});
});

How to run php code inside a template for node.js

There is some code to establish a node.js server with a html engine:
const express = require('express');
const paypal = require('paypal-rest-sdk');
var cons = require('consolidate');
var path = require('path');
const app = express();
app.engine('html', cons.swig)
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.get('/', (req, res) => res.render('index.html'));
However in my index.html file I wanna output some PHP variables. Let's say these look as follows:
<p class="places">
<?php echo $request['places_count'].' places are left now'; ?>
</p>
Is that even possible to show php veriables inside node.js and if not, what's the best way to solve the issue?

Integrating Pusher to a simple php web app

Hello stackoverflow community, I am learning how to implement Pusher API http://pusher.com into this simple web chat app. I was following a video tutorial and did every step correctly, but when I try to send a msg, it will be displayed correctly on my web browser, but will not be displayed or refreshed on another web browser. I will add my 2 php files, they are short.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Pusher Messenger</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://js.pusher.com/3.1/pusher.min.js"></script>
<script>
// Enable pusher logging - don't include this in production
//Pusher.logToConsole = true;
var pusher = new Pusher('your pusher key here', {
encrypted: true
});
var channel = pusher.subscribe('channel_pusher');
channel.bind('new_message', function(response){
$('#sent_messages').append('<li>' + response.message + '</li>');
});
$(function(){
$('form').submit(function(){
$.post('ajax.php', { msj : $('#input_mensaje').val() }, function(response){
//funcion de callback
$('#sent_messages').append('<li>' + response.message + '</li>');
}, 'json');
return false;
});
});
</script>
</head>
<body>
<form action="" methor="post">
<input type="text" id="input_mensaje" />
<input type="submit" class="submit" value="Send" />
</form>
<ul id="sent_messages">
<!-- Sent messages will be shown here -->
</ul>
</body>
</html>
And this is my ajax.php file:
<?php
require('lib/Pusher.php');
$options = array(
'encrypted' => true
);
$message = $_POST['msj'];
$pusher = new Pusher(
'code provided by pusher',
'code provided by pusher',
'code provided by pusher',
$options
);
$pusher->trigger(
'channel_pusher',
'new_message',
array('message' => $message)
);
echo json_encode(array('message' => $message));
?>
I have just tested your code with my own app key and it seems to work fine.
I did notice, however, that while you included your app key and secret in the ajax.php you quoted (which should normally be avoided), your HTML only contains
var pusher = new Pusher('your pusher key here',
Please make sure to provide the app key in both files so that both can actually communicate with Pusher.
Another thing to note is that your ajax.php currently passes a message submitted from the page both to Pusher and also back to the page itself.
The upshot of this is that the page that submitted the message will in fact append it twice, once from the response returned by ajax.php and once upon the new_message event being received from Pusher.
This may or may not be what you had in mind.

500 internal server error while posting data to database with laravel 5 and ajax

Hi guys? am trying to post data to the database using laravel 5 and ajax..am also applying using csrf protection by adding
<meta name="_token" content="{!! csrf_token() !!}"/>
to my layout header and adding the following code to my footer:
<script type="text/javascript">
$.ajaxSetup({
headers: { 'X-CSRF-Token' : $('meta[name=_token]').attr('content') }
});
</script>
This is my form:
<form action="{{action('QuizController#postQuiz')}}" method="POST">
<div id="name-group" class="form-group">
<label for="name">Please type your question here</label>
<input type="text" class="form-control" name="question">
</div>
<button type="submit" class="btn btn-success">Submit <span class="fa fa-arrow-right"></span></button>
</form>
This is my JS code:
var formData = {
'question' : $('input[name=question]').val(),
};
// process the form
$.ajax({
type : 'POST',
url : 'quiz',
data : formData,
dataType : 'json',
encode : true
})
// using the done promise callback
.done(function(data) {
// log data to the console to see
console.log(data);
// ALL GOOD! just show the success message!
$('form').append('<div class="alert alert-success">' + data.message + '</div>');
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
This is my route:
Route::post('create/quiz', array(
'as' => 'post-quiz',
'uses' => 'QuizController#postQuiz'
));
When my controller is like the following:
public function postQuiz()
{
if(Request::ajax()) {
$question = Request::get('question');
$data['success'] = true;
$data['message'] = $question;
echo json_encode($data);
}
the ajax call works and it returns,
Object {success: true, message: "test question"}
but when I try posting data to the database using:
public function postQuiz()
{
if(Request::ajax()) {
$question = Request::get('question');
DB::table('questions')->insert([
'question' => $question,
]);
}
I get the following from the console
POST http://localhost/leoschool-laravel5/public/create/quiz 500 (Internal Server Error)
and
Object {readyState: 4, responseText: "{"success":true,"message":"test question"}<!DOCTYPE htm…l>↵</div>↵↵ </div>↵ </body>↵</html>", status: 500, statusText: "Internal Server Error"}
What could be the problem? Thanks..
A good place to start is with Chrome Developer tools. Load your page with the tools open and fire the event that does the AJAX request.
Under the network tab of the tools, it will show you every request made and allow you to preview the response as if you were not using AJAX. This will show you the laravel stack trace. I think the problem is that you're using facades and they're not namespaced correctly.
Change your controller function to this and see if it works:
public function postQuiz()
{
if(\Request::ajax()) {
$question = \Request::get('question');
\DB::table('questions')->insert([
'question' => $question,
]);
}
With the above instruction on how to use dev tools and with the corrected code, you should be able to fix your problem. A better way to write this code would look like this though:
// assuming you have these models setup
// this uses dependency injection
public function postQuiz(Request $request, Question $question)
{
if($request->ajax()) {
$newQuestion = $request->get('question');
//add fields here to create new question with
$question->create([ /*stuff*/ ]);
}

Categories