I’m developing a website using vanilla HTML, CSS, and JavaScript, and I have a Python script that runs an AI model. To facilitate interaction between JavaScript and Python, I set up a Flask server.
When I send a request from JavaScript, the Flask server receives it correctly, the AI model executes successfully, and I receive a 200 status code in the command line. However, the JavaScript code returns the following error: “TypeError: Failed to Fetch”.
I’m starting the Flask server first and then using Visual Studio Code’s live server for the HTML page.
Below are the relevant files for my flask server and javascript code:
Flask Server (app.py):
import json
import traceback
from flask import Flask, request, jsonify, render_template, send_from_directory
from diagnose import diagnose
from werkzeug.utils import secure_filename
import os
from flask_cors import CORS
import sys
# Get the absolute path to the project root
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
UPLOADS_FOLDER = os.path.join(PROJECT_ROOT, 'uploads')
app = Flask(__name__, static_folder='../')
CORS(app, resources={
r"/diagnose": {
"origins": ["http://127.0.0.1:5000", "http://localhost:5000", "http://127.0.0.1:5500"],
"methods": ["POST"],
"allow_headers": ["Content-Type", "Accept"],
"expose_headers": ["Content-Type"]
}
})
# Add detailed logging
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
@app.route('/diagnose', methods=['POST'])
def diagnose_plant():
try:
# Extensive logging of request details
logger.debug("Diagnosis request received")
logger.debug(f"Form data: {request.form}")
logger.debug(f"Files data: {request.files}")
print("Diagnosis request received")
print(f"Form data: {request.form}")
print(f"Files data: {request.files}")
# Check if image is present in the request
if 'image' not in request.files:
logger.error("No image file in request")
print("No image file in request")
return jsonify({'error': 'No image file'}), 400
# Get the uploaded image file
image_file = request.files['image']
# Check if filename is empty
if image_file.filename == '':
logger.error("No selected file")
print("No selected file")
return jsonify({'error': 'No selected file'}), 400
# Save the image file to the uploads directory
filename = secure_filename(image_file.filename)
filepath = os.path.join(UPLOADS_FOLDER, filename)
# Ensure uploads directory exists
os.makedirs(UPLOADS_FOLDER, exist_ok=True)
image_file.save(filepath)
# Get the plant type from the request form data
plant_type = request.form['plant_type']
logger.debug(f"Diagnosing {plant_type} with image: {filepath}")
print(f"Diagnosing {plant_type} with image: {filepath}")
# Diagnose the plant disease using the uploaded image
try:
diagnosis = diagnose(plant_type, filepath)
logger.debug(f"Diagnosis result: {diagnosis}")
print(f"Diagnosis result: {diagnosis}")
except Exception as diagnose_error:
logger.error("Error in diagnosis process")
logger.error(traceback.format_exc())
print("Error in diagnosis process")
print(traceback.format_exc())
return jsonify({
'error': 'Diagnosis failed',
'details': str(diagnose_error),
'traceback': traceback.format_exc()
}), 500
response = jsonify({'diagnosis': diagnosis})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
except Exception as e:
# Log the full error traceback
logger.error("Unexpected error during diagnosis")
logger.error(traceback.format_exc())
print("Unexpected error during diagnosis")
print(traceback.format_exc())
# Return a more detailed error response
return jsonify({
'error': 'Diagnosis failed',
'details': str(e),
'traceback': traceback.format_exc()
}), 500
finally:
# Optional: Remove the uploaded file after processing
if 'filepath' in locals() and os.path.exists(filepath):
os.remove(filepath)
if __name__ == '__main__':
app.run(debug=True)
JavaScript (app.js):
// Get the image file input element
const imageInput = document.getElementById('file-input');
// Get the dropdown element
const plantDropdown = document.getElementById('plant-dropdown');
const plantConversions = {
'Select Plant Type': null,
'Apple': 'Apple',
'Cherry': 'Cherry_(including_sour)',
'Corn': 'Corn_(maize)',
'Grape': 'Grape',
'Peach': 'Peach',
'Bell Pepper': 'Pepper,_bell',
'Potato': 'Potato',
'Strawberry': 'Strawberry',
'Tomato': 'Tomato'
}
const diagnoseButton = document.getElementById('diagnose-button');
console.log(diagnoseButton)
// Add an event listener to the diagnose button
diagnoseButton.addEventListener('click', async (event) => {
console.log('Button clicked'); // Debug point 1
const plantType = plantDropdown.options[plantDropdown.selectedIndex].text;
console.log('Plant type:', plantType); // Debug point 2
if (!plantConversions[plantType]) {
alert('Please select a valid plant type');
return;
}
const imageFile = imageInput.files[0];
console.log('Image file:', imageFile); // Debug point 3
if (!imageFile) {
alert('Please select an image');
return;
}
const formData = new FormData();
formData.append('image', imageFile);
formData.append('plant_type', plantConversions[plantType]);
console.log('FormData created with:'); // Debug point 4
for (let [key, value] of formData.entries()) {
console.log(key, ':', value);
}
try {
console.log('Starting fetch...');
const response = await fetch('http://127.0.0.1:5000/diagnose', {
method: 'POST',
body: formData,
headers: {
'Accept': 'application/json'
},
mode: 'cors', // Explicitly state we're making a CORS request
credentials: 'omit' // Don't send credentials for cross-origin requests
});
console.log('Fetch completed, response:', response);
const data = await response.json();
console.log('Response data:', data);
if (data && data.diagnosis) {
alert(data.diagnosis);
} else {
alert('Invalid response format from server');
}
} catch (error) {
console.error('Detailed error:', {
name: error.name,
message: error.message,
stack: error.stack
});
alert(`Error: ${error.message}`);
}
});
I am unsure which specific console and terminal outputs would be most helpful to provide, but I have a significant amount of output data available.
Key Points:
Flask server receives request and processes AI model successfully.
AI model provides correct output, and 200 status code is returned.
JavaScript fetch request fails with “TypeError: Failed to Fetch”.
Flask server is started first, followed by VS Code live server for the HTML page.
Question: What could be causing the “TypeError: Failed to Fetch” error in my JavaScript code, and how can I resolve this issue?
What I Tried:
Verified that the Flask server is running and accessible.
Confirmed that the AI model executes and returns the expected results on the server side.
Ensured that the JavaScript code is correctly sending the fetch request.
Checked for any errors in the console and terminal outputs to identify the issue.
What I Expected: I expected the JavaScript fetch request to successfully communicate with the Flask server, retrieve the AI model’s output, and handle the response without encountering the “TypeError: Failed to Fetch” error.