I'm trying to upload a file in my local webserver but I'm running into an error that I don't fully understand. I think there might be an issue with my PHP script.
Here is my code :
JS :
addImageBlobHook: (blob, callback) => {
let formData = new FormData();
// file in a 'multipart/form-data' request
formData.append(0, blob, blob.name);
fetch('upload', {
method: 'POST',
body: formData
}).then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Server or network error');
}).then(response => {
if (!response.success) {
throw new Error('Validation error');
}
callback(response.data.url, 'alt text');
}).catch(error => {
console.log(error);
})
}
PHP :
<?php
if(isset($_FILES['file']['name'])){
// file name
$filename = $_FILES['file']['name'];
// Location
$location = 'upload/'.$filename;
// file extension
$file_extension = pathinfo($location, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
// Valid extensions
$valid_ext = array("jpg","png","jpeg");
$response = 0;
if(in_array($file_extension,$valid_ext)){
// Upload file
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
$response = 1;
}
}
echo $response;
exit;
}
else echo json_encode(2);
I'm getting the following error :
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
on line 85, which is in my code the console.log(error); in the JS file.
EDIT:
Replacing isset($_FILES(['file.....) with just isset($_FILES) allow to enter the 'if' and make a vardump, like so :
if(isset($_FILES)){
var_dump($_FILES);
Which returns :
C:\wamp64\www\toast\upload.php:5:
array (size=1)
0 =>
array (size=5)
'name' => string 'Beer_mug_transparent.png' (length=24)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 3
'size' => int 0
You are just echo the response. Which does not give proper response. Please see updated php code.
<?php
if(isset($_FILES['file']['name'])){
// file name
$filename = $_FILES['file']['name'];
// Location
$location = 'upload/'.$filename;
// file extension
$file_extension = pathinfo($location, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
// Valid extensions
$valid_ext = array("jpg","png","jpeg");
$response = 0;
if(in_array($file_extension,$valid_ext)){
// Upload file
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
$response = 1;
}
}
echo json_encode($response);
exit;
}
Related
After adding http response code in the login file axios is returning these errors even if the login email and password are correct and the catch block isn't executed I get these errors. If I remove the http_response_code(400) it will work and return the user or the message with 200 ok but I don't want that.
How do i fix it? thanks in advance.
Access to XMLHttpRequest at 'http://localhost/classroom-api/api/user/login.php' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
POST http://localhost/classroom-api/api/user/login.php net::ERR_FAILED
login.php
<?php
// Headers
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Access-Control-Allow-Headers,Content-Type,Access-Control-Allow-Methods, Authorization, X-Requested-With');
require_once '../../vendor/autoload.php';
use Firebase\JWT\JWT;
require_once '../../config/Database.php';
require_once '../../models/User.php';
// Connect db
$database = new Database();
$db = $database->connect();
$user = new User($db);
try {
// Get posted data
$data = json_decode(file_get_contents("php://input"));
if(empty($data->email) || empty($data->password)) {
throw new Exception("Please enter all fields");
}
$user->email = $data->email;
$user->password = $data->password;
if ($user->login()) {
// Create token
$key = 'ajdZiWodDaAs1123';
$iat = time();
$payload = [
'iss' => 'localhost',
'aud' => 'localhost',
'iat' => $iat,
'nbf' => $iat,
'exp' => $iat + 259200000, // 3 days
'data' => [
"id" => $user->id
]
];
$token = JWT::encode($payload, $key, 'HS256');
echo json_encode(
array(
"id" => $user->id,
"full_name" => $user->fname ." ".$user->lname,
"email" => $user->email,
"token" => $token
)
);
} else {
throw new Exception("Invalid credentials");
}
} catch (Exception $e) {
http_response_code(400);
echo json_encode(
array('message' => $e->getMessage())
);
}
?>
axios
import axios from 'axios';
const base_url = 'http://localhost/classroom-api';
const route = '/api/user';
export const login = async (userData) => {
const res = await axios.post(base_url + route + '/login.php', userData);
console.log(res);
};
although it does work in postman
Browsers will first send an OPTIONS request to check for CORS headers.
Add this right after the headers:
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS')
exit('ok');
Here is my GET request which works:
function getTodos() {
fetch(window.location.href + 'api/todo')
.then(response => response.json())
.then(json => drawTodos(json))
.catch(error => showToastMessage('Failed to retrieve todos...'));
}
But now I am trying to do a POST request but it fails
todo as shown in console.log
{
"id": "ghCWaYWQTh",
"title": "aaa",
"description": "bbb",
"done": false
}
function postTodo(todo) {
let options = {
method : 'POST',
headers : {
"Content-type": "application/json"
},
body : JSON.stringify(todo)
};
console.log(options);
fetch(window.location.href + 'api/todo',options)
.then(response => response.json()) // convert to json
.then(json => console.log(json)) //print data to console
.catch(err => console.log('Request Failed', err)); // Catch errors
console.log(todo);
}
I cannot see a syntax error in my options variable?
-- the backend is in PHP --
I cannot see a syntax error in my options variable?
-- the backend is in PHP the get request works the post fails --
$requestType = $_SERVER['REQUEST_METHOD'];
$body = file_get_contents('php://input');
$pathCount = count($path);
require_once "dbconfig.php";
switch ($requestType) {
case 'GET':
$query = "select * from todos";
$result = mysqli_query($conn, $query);
$todos = array();
while($todo = mysqli_fetch_assoc($result)) {
$todos[] = $todo;
}
echo json_encode($todos);
break;
case 'POST':
$data = json_decode($body);
$id = $data->id;
$title = $data->title;
$description = $data->description;
$done = $data->done;
$query = "INSERT INTO todos(id, title, description, done)
VALUES ('" . $id . "', '" . $title . "', '" . $description . "', " . $done . ")";
// echo $query;
if (mysqli_query($conn, $query) or die("Insert Query Failed")) {
echo json_encode(array("message" => "Todo Inserted Successfully", "status" => true));
} else {
echo json_encode(array("message" => "Failed ToDo Not Inserted ", "status" => false));
}
break;
default:
http_response_code(501);
die();
break;
This POST works with Postman, but not from Javascript
Your error is throwed from this
.then(response => response.json()) // convert to json
Because your response from BE API is 500 and the body of response can not be convert to Json
So i got this POST json method here, but can't understand how to get my json data
It's packed in BLOB which is packed in FormData
How to receive such POST in php? (and convert this FormData(Blob) back to json?)
JS
const data = new FormData();
const jsonBlob = new Blob([JSON.stringify(myJSON)], {type: "application/json"});
data.append("data", jsonBlob);
fetch(website,{
method: "POST",
body: data,
}).then(resp=>{
if(!resp.ok){
const err = new Error("Error response");
err.resp = resp;
throw err;
}
console.log("OK");
}).catch(err =>{
console.error(err);
})
I'm big noobo, so i can't even receive it
Seems like it works differently with fetch()
PHP
if(isset($_POST['data'])){
}
The simpliest way to send a JSON to server is to simply send it as the POST request body. There is no need to wrap it like a file. For example,
var myJSON = {
hello: 'world',
foo: 'bar',
};
fetch(website, {
method: "POST",
body: JSON.stringify(myJSON),
})
On server side, your message will be readable through the "php://input" stream. You can read it like an ordinary file:
$request_raw = file_get_contents('php://input');
$json_object = json_decode($request_raw);
You can save the below code as a PHP file and test it yourself. On load, it would send itself another POST reqeust, parse it as key-value pairs, return it to your browser and show it:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$request_raw = file_get_contents('php://input');
$request = json_decode($request_raw);
foreach ($request as $key => $value) {
echo "{$key}: {$value}\n";
}
exit;
}
?>
<div id="result"></div>
<script>
var myJSON = {
hello: 'world',
foo: 'bar',
};
const data = new FormData();
fetch(document.location.href, {
method: "POST",
body: JSON.stringify(myJSON),
}).then(resp => {
if(!resp.ok){
const err = new Error("Error response");
err.resp = resp;
throw err;
}
console.log("OK");
return resp.text();
}).catch(err =>{
console.error(err);
}).then(body => {
document.getElementById('result').innerText = body;
});
</script>
I have an existing PHP code that is doing a curl request to a 3rd-party PHP server.
The 3rd-party server returns a GZIP string.
In PHP, I can use gzdecode to decode the gzip string.
How can I do it in NodeJS/Javascript? I tried using decompress-response with no avail.
Also tried using got instead of request, enabled auto-decompress, also doesn't work.
Edit: Also tried zlib and pako, also doesn't work.
Sample Code [ PHP ]
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $params,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 3000000,
CURLOPT_ENCODING => '',
CURLOPT_CUSTOMREQUEST => "GET",
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo false;
} else {
$response = gzdecode($response);
echo $response;
}
This is the solution that works for me.
I used got instead of axios because I can't get it to work there.
I set my request options:
const requestOptions = {
encoding: null, // this is important
headers: {
"Accept-Encoding": "gzip",
}
...
};
Don't forget that encoding: null line, because without that, the response will be automatically converted to a string. ( We need a buffer to make this work )
Then I created a function like this to handle my request:
const zlib = require("zlib");
async function performRequest(url, options) {
try {
const response = await got(url, options);
if (response.headers["content-encoding"] === "gzip") {
const body = response.body;
try {
const dezziped = zlib.gunzipSync(response.body);
response.body = JSON.parse(dezziped.toString());
} catch (error) {
response.body = body;
}
}
return response.body;
} catch (error) {
return error;
}
}
Note: This is a synchronous operation, you can use gunzip instead if you want to do the async way.
Here is my curl command is there anyway to execute this command using ajax
curl -X POST -u "CONVERSATION_USERNAME":"CONVERSATION_PASSWORD" -H "Content-Type:application/json" -d "{\"input\": {\"text\":\" \"}}" "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11"
This should work.
$.ajax({
url: "https://conversation_username:conversation_password#gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11",
method: "POST",
headers: {
"Content-Type": "application/json"
},
data: {
input: {
text: " "
}
}
})
done(function(data) {
// handle success response
})
.fail(function(err) {
// handle error response
});
http://api.jquery.com/jquery.ajax/
edit - updated to handle success and error responses using promises.
Create a php file, put that command inside that file, return from it whatever you need from the curl response and call this php file via ajax.
file ajax_curl.php
<?php
//do your curl call here
//curl -X POST -u "CONVERSATION_USERNAME":"CONVERSATION_PASSWORD" -H "Content-Type:application/json" -d "{\"input\": {\"text\":\" \"}}" "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/CONVERSATION_ID/message?version=2016-07-11"
//see http://php.net/manual/en/curl.examples-basic.php
//do a return like so if $url is you url
$defaults = array(
CURLOPT_URL => $url,
your_other_params => go_here,
CURLOPT_RETURNTRANSFER => 1
);
$ch = curl_init();
curl_setopt_array($ch, $defaults);
$result= curl_exec($ch);
if( ! $result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
echo json_encode($result);
?>
your calling js looks like
$.post( "ajax_curl.php", { passed_data: "pass_whatever_you_need" }, function( data ) {
console.log( data );
}, "json");
'data' now contains a json with the response from your curl call
Create a PHP file.here file name is chat.php
<?php
if(isset($_POST['conversation'])) {
$data = array("input"=>array("text"=>$_POST["conversation"]));
$url = "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/a9379972-d820-4cdf-b1cb-ad0af898a534/message?version=2016-07-11";
$ch = curl_init($url);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_USERPWD => "username:password",
CURLOPT_HTTPHEADER => array("Content-Type:application/json"),
CURLOPT_POSTFIELDS => json_encode($data),
));
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response));
}
?>
and call this by using Ajax
var xhr = new XMLHttpRequest();
//xhr.open('get', 'chat.php');
xhr.open("GET", "chat.php?data=" + data to be pass, false);
// Track the state changes of the request.
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
//alert(xhr.responseText);
talking = true;
botMessage=xhr.responseText;// 'This is the returned text.'
} else {
// console.log('Error: ' + xhr.status); // An error occurred during the request.
alert ('Error: ' + xhr.status);
}
}
};
// Send the request to send-ajax-data.php
xhr.send();