I'm trying to upload images to Cloudinary from my React Native app, but I'm getting the "400 Bad Request" saying the image I'm sending is ""x-cld-error": "Unsupported source URL".
ImageUpload.js
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1
})
if (!result.cancelled) {
setImageSource(result.uri);
}
}
I'm currently using the ImagePicker from expo-image-picker. I'm taking the imageSource I've obtained from above and appending it to data before sending it to Cloudinary. The result.uri shows the URL of the picture from the iOS simulator.
CreatePost.js
const uploadFile = async () => {
const data = new FormData();
data.append('file', imageSource);
data.append('upload_preset', 'test_folder')
const res = await fetch('https://api.cloudinary.com/v1_1/{my_cloudinary}/image/upload', {
method: 'POST',
body: data,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
})
const file = await res.json()
setImage(file.secure_url)
setLargeImage(file.eager[0].secure_url)
}
When I console.log res, it shows that the status is 400.
You can try using ajax. For example here:
<h1>Upload to Cloudinary with FormData</h1>
<div>
<p>
Set your cloud name in the API URL in the code: "https://api.cloudinary.com/v1_1/<strong><cloud name></strong>/image/upload" before running the example.
</p>
</div>
<form action="" method="post" enctype="multipart/form-data" onsubmit="AJAXSubmit(this); return false;">
<fieldset>
<legend>Upload example</legend>
<p>
<label for="upload_preset">Unsigned upload Preset: <input type="text" name="upload_preset">(set it here)</label>
</p>
<p>
<label >Select your photo:
<input type="file" name="file"></label>
</p>
<p>
<input type="submit" value="Submit" />
</p>
<img id="uploaded">
<div id="results"></div>
</fieldset>
</form>
enter code here https://jsfiddle.net/shirlymanor/s1hou7zr/
Related
I am using formData to send details to my backend but somehow my image path isn't being sent.
Post photo
<div className="form-group">
<label className="btn btn-block btn-success">
<input
onChange={handleChange("photo")}
ref={inputRef}
type="file"
name="photo"
accept="image"
placeholder="choose a file"
/>
</label>
</div>
this is the form i am using
Handle change and submit button
const onSubmit = (event) => {
event.preventDefault();
setValues({...values,error:"",loading:true});
createProduct(user._id,token,JSON.stringify(values))
.then(data=>{
if(data.error){
setValues({...values,error:data.error});
}else{
setValues({...values,
name:"",
description:"",
price:"",
photo:"",
stock:"",
createdProduct:data.name,
loading:false});
}
}).then(response=>{
})
.catch(err=>console.log(err));
//
};
const handleChange = name => event => {
const value=name==="photo"?event.target.files[0]:event.target.value;
formData.append(name,value)
setValues({...values,[name]:value});
//
};
And this is the api call to backend
export const createProduct=(userId,token,product)=>{
console.log(product)
return fetch(`${API}/product/create/${userId}`,{
method: "POST",
headers:{
Accept: "application/json",
Authorization: `Bearer ${token}`
},body:product
})
.then(response=>{
return response.json();
})
.catch(err=>console.log(err));
}
The api is working fine with postman , I am using formidable in backend. Some answers from stack made the path of the file have c:\fakepath and so m too confused what to do .
Thanks for help.
disclaimer: this is not a replica of another post, I am trying a different approach to get the solution of this problem.
problem: cloudinary most recent uploaded image overwrites all displayed images
goal: to get the uploaded image url to be submitted alongside with the form to the backend (user choses the image and input field auto populates ) , in the back end I will be able to retrieve the image url which will have a mongodb id related to the form data so I woulld inject the img tag with the url of different image each time I upload an image
The way the app is set up : I have a form and. GUI to display the data. the form is stored inside (state) and I am using Cloudinary to upload the images which store the uploaded image inside a different state called (image). so far I have managed to get the url of the uploaded image but I need a way to submit it alongside with the form
any ideas how to do that ??
form
<form onSubmit={props.handleSubmit} >
<div >
<div >
<label >Track name<input name="track" value={props.state.newTrack.track} onChange={props.handleChange} /></label>
</div>
<div >
<label >Artist name<input name="artist" value={props.state.newTrack.artist} onChange={props.handleChange} /></label>
</div>
<div >
<label >album<input name="album" value={props.state.newTrack.album} onChange={props.handleChange} /></label>
</div>
<div >
<label > Year<input name="year" value={props.state.newTrack.year} onChange={props.handleChange} /></label>
</div>
<div >
<label >URL<input name="url" value={props.image} value={props.state.newTrack.url} onChange={props.handleSubmit} /></label>
</div>
<div >
<label > Upload<input name="url" type="file"
// value={props.state.newTrack.url}
onChange={(e) => {
setImageSelected(e.target.files[0]);
}} />
</label>
</div>
<button class="formdiv" onClick={uploadImage} > {props.state.editMode ? 'Edit ' : 'Add '}</button>
</div>
</form>
cloudinary upload image function
const [imageSelected, setImageSelected] = useState('');
console.log(imageSelected)
const uploadImage = () => {
const formData = new FormData()
formData.append('file', imageSelected)
formData.append('upload_preset', 'musicimages')
Axios.post(
' https://api.cloudinary.com/v1_1/dklcmfo0q/image/upload', formData)
.then((res) => {
props.setImage(res.data.url);
})
};
function create track
function createTrack(data){
return fetch(BASE_URL, {
method:'POST',
headers: {
'Content-type' : 'Application/json'
},
body: JSON.stringify(data)
}).then(res => res.json())
setting state of tracks
const track = await createTrack(state.newTrack);
// console.log(image)
setState({
tracks: [...state.tracks, track],
newTrack: {
track: "",
artist:"",
album: "",
year:"",
url:""
}
})
Make sure the file imageSelected that you are uploading with fd.append(‘file’, imageSelected); is a file object and not just the name of the file.
You can verify by logging it. Here’s some sample vanilla JS that might help. https://codepen.io/team/Cloudinary/pen/QgpyOK
I'm trying to upload a video from react to flask but when I make a POST request it gives me this error
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'file'
here is the backend:
#app.route("/releaseVideo",methods=["POST"])
def release():
request_data = request.files.get["file"]
print(request_data)
try:
request_data.save(os.path.join(app.config['UPLOAD_FOLDER'],'first video'))
except Exception:
print('COULD NOT')
return {"msg":"What am I DOING"},200
if __name__ == '__main__':
app.run(debug=True)
Here is the front end...I'm using axios instead of fetch because I heard that axios is better for file uploads than fetch .
const upload_file = (event) => {
event.preventDefault()
let file = document.querySelector('input[type="file"]')
const formdata = new FormData()
formdata.append("file",file);
axios("/releaseVideo", {
method:'POST',
body:formdata
})
.then(res => console.log(res))
.catch(err => console.warn(err));
}
return (
<>
<form onSubmit={upload_file}>
<label>Title: </label><br />
<input type="text" onChange={onTitleChange} value={title}/><br />
<label>Description:</label><br />
<textarea value={textArea} onChange={onTextAreaChange}></textarea>
<input type="file" id="file"/>
<input type="submit" value="Upload Video!" />
</form>
</>
)
So how can I get the video from the front end in a proper way?
I am currently new to using React and express, I wish to send data which i have received from a form. The data i would like to send back is the UserInfo or email which is in the state. However I am extremely unsure how I am supposed to go about this request.
class ForgotPassword extends Component {
constructor() {
super()
this.state = {
email:'',
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
componentDidMount = () =>{
// this.fetchUserInfo();
}
handleChange = (e) => {
this.setState ({
[e.target.id]: e.target.value
})
console.log(this.state);
}
handleSubmit = async (e) => {
e.preventDefault();
const userInfo = {
email : this.state.email
};
fetch("/forgotpassword", {
method: "POST",
body: JSON.stringify(userInfo),
headers: { "Content-Type": "application/json" }
})
.then(response => {
return response.json();
})
.then(jsonData => {
console.log(jsonData);
})
.catch(err => {
console.log("Error with data fetch " + err);
});
};
This is my form...
<div className='row'>
<div className='col'></div>
<div className='col card form'>
<h1 id="title">Reset Password</h1>
<h5 id="passinstruc">Please enter your email to reset your password</h5>
<form id="forgotpass" onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email </label>
<input onChange={this.handleChange} type="email" className="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email" value={this.state.email} />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<button id="loginbtn" type="submit" className="btn btn-primary btn-lg btn-block" >Submit</button>
<br/>
<div className='division'>
<Link to="/register" className='btn btn-primary btn-lg btn-block' id="registerbtn" > Create your account here</Link>
</div>
</form>
</div>
In my backend I am getting a POST /forgotpassword 404 message but I dont know why. Help would be much appreciated.
This is my backend route where I will be sending the information
var express = require('express');
var router = express.Router();
var connection = require ('../connection');
var email = require ('./sendEmail');
router.post('/forgotpassword', function(req, res, next) {
console.log(req.email);
var userEmail = req.email;
var text = "Follow the instructions below to reset your password"
email.sendEmailWithTemplate(userEmail,'PetS.o.S Password Reset', text);
});
For sending data you will need the domain name or ip address of your server.
Once you obtained that, you can use jQuery.get - https://api.jquery.com/jQuery.get/
or jQuery.post -
https://api.jquery.com/jQuery.post/
Or if you are not using jQuery, use XMLHttpRequest -
https://www.w3schools.com/xml/xml_http.asp
Instead of sending data in body send it in response.
https://www.freecodecamp.org/news/create-a-react-frontend-a-node-express-backend-and-connect-them-together-c5798926047c/
fetch('/api/getList')
.then(res => res.json())
.then(list => this.setState({ list }))
https://dev.to/nburgess/creating-a-react-app-with-react-router-and-an-express-backend-33l3
I am working on login page with ReactJs,Spring Boot and rest web services.My Reactjs frontend application is running on port 8080 while my webservice/spring boot application is running on port 9090. I am trying to use the "fetch" method to connect with my backend code, but I am facing error while passing headers in fetch request. If I remove headers property, execution goes into the called backend method. I need to pass Headers in fetch method as it required to access them in web service method.
Please find Snapshot of network requests and responses. Without Headers With headers
Below is my code of React JSX file:
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state={
email:'',
password:''
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(){
var usernameFieldValue = this.refs.emailField.value;
var passwordFieldValue = this.refs.passwordField.value;
this.setState({email:usernameFieldValue})
this.setState({password:passwordFieldValue})
//var headers = 'Basic bmltZXNoLnBhdGVsQHRhdHZhc29mdC5jb206cGFzc3dvcmQ=';
//alert(headers);
fetch('http://192.168.0.239:9090/ws/login',{
mode: 'cors',
method: 'get',
headers: {
"Content-Type": "application/json",
"Authorization": "Basic bmltZXNoLnBhdGVsQHRhdHZhc29mdC5jb206cGFzc3dvcmQ="
}
}).then((response) => response.json())
.then((responseJson) => {
alert(" responseJson : " + responseJson);
})
.catch((error) => {
alert("Error : " +error);
});
}
render() {
return (
<div id="loginFrame">
<div className="container">
<div id="loginHeader" className="row">
<div className="col-xs-12 text-center">
<img src="" alt="'Logo" />
</div>
</div>
<div id="loginBody" className="row">
<div className="col-xs-6 col-xs-offset-3">
<div className="center-block">
<div id="login-panel">
<form id="loginForm" className="form-horizontal" role="form">
<div className="form-group">
<input type="text" className="form-control input-lg" id="email" name="email" ref="emailField" placeholder="Email address"/>
</div>
<div className="form-group">
<input type="password" className="form-control input-lg" id="password" name="password" ref="passwordField" placeholder="Password"/>
</div>
<div className="form-group">
<button onClick={this.handleClick} className="btn btn-lg btn-success pull-right">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
var url = "https://yourUrl";
var bearer = 'Bearer '+ bearer_token;
fetch(url, {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
'Authorization': bearer,
'X-FP-API-KEY': 'iphone',
'Content-Type': 'application/json'}
}).then((responseJson) => {
var items = JSON.parse(responseJson._bodyInit);
})
.catch(error => this.setState({
isLoading: false,
message: 'Something bad happened ' + error
}));
You don't need mode: cors, this is default.
const headers = new Headers({
"Content-Type": "application/json",
"Authorization": "Basic bmltZXNoLnBhdGVsQHRhdHZhc29mdC5jb206cGFzc3dvcmQ="
});
fetch('http://192.168.0.239:9090/ws/login', {
method: 'GET',
headers,
}).then().then().catch();
Based on your comments, it sounds like the underlying problem is that you're doing a CORS request from your react app, which is being served from a different server than your spring backend. I don't know Spring, but adding a Access-Control-Allow-Origin HTTP header (as well as some other CORS related headers) will clear up the problem. I'm not 100% sure why when you fetch with no headers, it works. There may be a deeper configuration issue or you need to configure it to allow requests with those headers you're passing (Access-Control-Allow-Headers). Note that if you don't plan to allow cross-origin requests in production you may want to add those headers except when in development.
You can also fetch in no CORS mode (pass {mode: 'no-cors'}), but there's a lot of limitations to that and I doubt that's what you want.