i am using react as frontend and php as backend, frontend previously i was uploading on aws amplify and backend upload on lightsail, however due to amplify is https but lightsail is http api which wont let me pass the info so I changed to aws s3 as frontend, every function works fine but only update function will show error
Access to XMLHttpRequest at 'http://3.222.98.25/api/Update.php' from origin 'http://post-fetch-api.s3-website-ap-southeast-2.amazonaws.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
anyone knows reason? i put every CORS functions i can in the update file, is works on local enviorment, but not online enviorment
//this is php update page
<?php
// if request is OPTIONS, disconnect
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: token, Content-Type');
header('Access-Control-Max-Age: 1728000');
header('Content-Length: 0');
header('Content-Type: text/plain');
die();
}
// Headers
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Access-Control-Allow-Headers,Content-Type,Access-Control-Allow-Methods, Authorization, X-Requested-With');
include_once '../config/Database.php';
include_once '../models/Post.php';
// Instantiate DB & connect
$database = new Database();
$db = $database->connect();
// Instantiate blog post object
$post = new Post($db);
// Get raw posted data
$data = json_decode(file_get_contents("php://input"));
// Set ID to update
$post->id = $data->id;
$post->title = $data->title;
$post->body = $data->body;
// Update post
if($post->update()) {
echo json_encode(
array('message' => 'Post Updated')
);
} else {
echo json_encode(
array('message' => 'Post Not Updated')
);
}
// here is react update page
import { useState, useEffect } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";
export default function Update() {
const [inputs, setInputs] = useState({});
//const[post,setPost]=useState({});
const navigate = useNavigate();
const { id } = useParams();
useEffect(() => {
getSinglePost();
}, []);
function getSinglePost() {
axios
.get(`http://3.222.98.25/api/read_single.php?id=${id}`)
.then((res) => {
console.log(res.data);
setInputs(res.data);
})
.catch((err) => console.log(err));
}
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setInputs((values) => ({ ...values, [name]: value }));
};
const handleSubmit = (e) => {
e.preventDefault();
axios
.put("http://3.222.98.25/api/Update.php", inputs)
.then((response) => {
console.log(response.data);
navigate("/read");
})
.catch((err) => console.log(err));
};
return (
<div>
<Link to="/">Show Posts</Link>
<h1 style={{ marginTop: "150px" }}>Update a post</h1>
<form onSubmit={handleSubmit}>
<div className="marginBottom">
<label className="marginRight">Title:</label>
<input
type="text"
value={inputs.title}
name="title"
onChange={handleChange}
required
></input>
</div>
<div className="marginBottom bodyCenter">
<label className="marginRight">Body:</label>
<textarea
style={{ height: "50px" }}
type="text"
name="body"
value={inputs.body}
onChange={handleChange}
required
></textarea>
</div>
<button>update</button>
</form>
</div>
);
}
Related
Given the following code:
fetch(mockproxy+myphp.php,{
method: 'POST',
headers:{'Token':token["token"]},
body: name,
}).then((response) => response.json())
.then((json)=>{
toast.success(JSON.stringify(json));
})
.catch((err) => {
toast.error(JSON.stringify(err));
})
}
mockproxy is helping bypass CORSS. The file looks like this:
const corsAnywhere = require('cors-anywhere');
const express = require('express');
const apicache = require('apicache');
const expressHttpProxy = require('express-http-proxy');
const CORS_PROXY_PORT = 5000;
// Create CORS Anywhere server
corsAnywhere.createServer({}).listen(CORS_PROXY_PORT, () => {
console.log(
`Internal CORS Anywhere server started at port ${CORS_PROXY_PORT}`
);
});
// Create express Cache server
let app = express();
// Register cache middleware for GET and OPTIONS verbs
app.get('/*', cacheMiddleware());
app.options('/*', cacheMiddleware());
// Proxy to CORS server when request misses cache
app.use(expressHttpProxy(`localhost:${CORS_PROXY_PORT}`));
const APP_PORT = process.env.PORT || 5080;
app.listen(APP_PORT, () => {
console.log(`External CORS cache server started at port ${APP_PORT}`);
});
/**
* Construct the caching middleware
*/
function cacheMiddleware() {
const cacheOptions = {
statusCodes: { include: [200] },
defaultDuration: 60000,
appendKey: (req, res) => req.method
};
let cacheMiddleware = apicache.options(cacheOptions).middleware();
return cacheMiddleware;
}
And the server is a shared server where I upload the PHP files so they can access to the DB. The php receives the data and give a response when I use postman but not when I execute the fetch from the dev website, I'm using react, I think it doesn't matter in this case.
The PHP file:
<?php
$headers = apache_request_headers();
header("Access-Control-Allow-Origin: *, ");
header("Access-Control-Allow-Methods: HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization");
header('Content-Type: application/json');
$method = $_SERVER['REQUEST_METHOD'];
if ($method == "OPTIONS") {
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization");
header("HTTP/1.1 200 OK");
exit;
}
if (isset($_POST["name"])) {
echo json_encode(" name" . $_POST["name"]); //returned on postman
}else{
echo json_encode("no name"); //returned on development.
}
exit;
So this is a code i use when i want to fetch all data from a form. You can obviously not loop through all forms like i do below but just your single form.
// Query all forms in the DOM or a specific one if you want
const forms = document.querySelectorAll('form');
// Loop through them
forms.forEach((form) => {
// if method is post
if (form.method === 'post') {
form.addEventListener('submit', (event) => {
// prevent default submit
event.preventDefault();
// prepare the data
let data = new FormData(form);
// fetch using the form's
fetch(form.action, {
method: 'post',
body: data,
})
// get the text() from the Response object
.then(response => response.text())
.then(text => {
// Display it in the result div
document.getElementById('result').innerHTML = text;
})
}, false);
// if not post (get really)
} else {
form.addEventListener('submit', (event) => {
// prevent default submit
event.preventDefault();
// build the URL query params from the submitted data
const data = new URLSearchParams(new FormData(form).entries());
// Fetch, URL is formed from the action, append ? and then the query params
fetch(form.action + '?' + data)
// get the text() from the Response object
.then(response => response.text())
.then(text => {
// Display it in the result div
document.getElementById('result').innerHTML = text;
})
}, false);
}
});
I am trying to upload images from my Angular 8+ frontend to my php backend and sending text data works without a problem, but wanting to send image files to a folder in my wamp directory, no cigar unfortunately...
It worked earlier, but this morning it decided it did not want to work anymore. I tried adding to the CORS headers, but nothing seems wrong there.
html:
<input type="button" value="Test" (click)='Advertise($event.target.files)'>
component:
ToUpload()
{
let images = this.carImages.nativeElement;
let j=10;
for(let i of images.files)
{
console.log(i);
if(i.type=='image/jpeg')
{
let frmData = new FormData();
frmData.append('file',i,(j+'.jpg').toString());
this.uploadService.UploadImages(frmData).subscribe(val=>
{
})
}
if(i.type=='image/png')
{
let frmData = new FormData();
frmData.append('file',i,(j+'.png').toString());
this.uploadService.UploadImages(frmData).subscribe(val=>
{
})
}
j++;
}
}
Advertise(files:FileList)
{
this.ToUpload();
}
service:
UploadImages(image:FormData):Observable<any>
{
return this.httpClient.post(this.apiURL+"/api/BLL/imageUpload.php?action=upload",image) as Observable<any>;
}
CORS_Headers.php
<?php
// Default Header
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization,Content-Range, Content-Disposition, Content-Description');
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Credentials: true");
header("MIME-Version: 1.0");
header("Content-type:text/html;charset=UTF-8");
// Response type header
header('Content-Type: application/json');
?>
imageUpload.php
<?php
require_once '../BLL/CORS_Headers.php';
//require '../DAL/DBHandler.php';
//use DAL\DBHandler;
$action=$_GET['action'];
if($action=='upload')
{
$tempPath = $_FILES['file']['tmp_name'];
// Get File Name
$actualName = $_FILES['file']['name'];
// New path
$actualPath = '../Images/' . $actualName;
//$tempPath = compressImage($tempPath,$actualPath,60);
// Move File into new path
move_uploaded_file($tempPath, $actualPath)
// Get real path of moved file here
$realPath = realpath(__DIR__ . '/' . $actualPath);
// Delete the file
echo "Uploaded";
}
Expected result: Just do the upload
Actual result: Access to XMLHttpRequest at 'http://localhost:3000/api/BLL/imageUpload.php?action=upload' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
and
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://localhost:3000/api/BLL/imageUpload.php?action=upload", ok: false, …}
try this
Add below Code in .htaccess file PHP(Server) side
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "X-Requested-With, content-type"
</IfModule>
Angular Code
page.html
<input type="file" (change)="fileUpload($event)" />
npm install
"rxjs": "~6.5.1", //npm i rxjs#6.5.1 --save
"rxjs-compat": "^6.5.2" // npm i rxjs-compat#6.5.2 --save
page.ts
import 'rxjs/add/observable/from';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/concatMap';
fileUpload(event){
let formData = new FormData();
formData.append('file', event.target.files[0]);
this.ImageUpload(formData).subscribe(val => {
//enter custom code
})
}
ImageUpload(formData):Observable<any>{
var token = localStorage.getItem('keyToken');
const myHeaders = new HttpHeaders({ 'Authorization': token });
return this.http
.post(URL, formData,{headers:myHeaders})
.concatMap(data=>{
return Observable.of(data);
})
}
I want to upload an image using angular 6 via php to mysql. After that, I want to retrieve the image
from the database to display it in the html. Here is my code:
export class Student {
idCard : string;
fname : string;
mname : string;
lname : string;
gender : string;
studentPhoto?: File; //what type of data should I use
}
For displaying the photo
student-details.component.html
<div class="col-xs-4">
<img class="imageClass" src="student.studentPhoto" alt="Image not Recognized"/>
</div>
<!-- how can I set the src attribute -->
So, what data type should I use in the angular and also in the MYSQL to store the image? and How can I display the image
by fetching it from MYSQL?
Here is the full implementation that solves the problem:
In the component class:
import { StudentService } from '../student-service.service';
import { DomSanitizer } from '#angular/platform-browser';
export class StudentRegistrationComponent implements OnInit {
imageUrl = null;
photo: Blob;
constructor(private _service: StudentService,
public _DomSanitizationService: DomSanitizer) { }
setPhoto(event){
this.photo = event.target.files[0];
}
onClickSubmit(){
const fd = new FormData();
fd.append('stphoto',this.photo);
this._service.postImage(fd).subscribe(res => console.log(res));
}
showImage(){
this._service.getImage().subscribe((res) => {
this.photo = res;
var myReader:FileReader = new FileReader();
myReader.onloadend = (e) => {
this.imageUrl = this._DomSanitizationService.bypassSecurityTrustUrl(<string>myReader.result);
}
myReader.readAsDataURL(this.photo);
});
}
}
In the template:
<input id="photo" name="studentPhoto" type="file" (change)="setPhoto($event)" class="form-control">
<button class="btn btn-primary" (click) = "onClickSubmit()">submit</button>
<button (click)="showImage()">showImage</button>
<img [src]="imageUrl" height="200" width="200" class="img-thumnail">
StudentService:
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class StudentService {
constructor(private httpClient: HttpClient) { }
postImage(fd : FormData): Observable<string>{
return this.httpClient.post<string>('http://localhost:4000/files/postImage.php', fd );
}
getImage(): Observable<Blob> {
return this.httpClient.get( 'http://localhost:4000/files/getImage.php', { responseType: 'blob' })
}
}
postImage.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
header('Access-Control-Allow-Credentials: true');
$con = mysqli_connect("localhost:3306","root","","students");
mysqli_set_charset($con, "utf8");
if($_FILES["stphoto"])
{
$tmporary = $_FILES["stphoto"]["tmp_name"];
$file_name = $_FILES["stphoto"]["name"];
//don't forget to change 'ABDU' to your username.
if(move_uploaded_file($tmporary,"C:\Users\ABDU\AppData\Local\_"."$file_name"))
{
if($file = addslashes(file_get_contents("C:\Users\ABDU\AppData\Local\_"."$file_name")))
{
$sql = "INSERT INTO imagedb (`imagefile`) VALUES ('$file')";
mysqli_query($con,$sql);
mysqli_query($con,"ALTER TABLE imagedb AUTO_INCREMENT = 1");
echo json_encode("successfully injected");
}
}
else
echo json_encode("error");
}
?>
getImage.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
header('Access-Control-Allow-Credentials: true');
$con = mysqli_connect("localhost:3306","root","","students");
mysqli_set_charset($con, "utf8");
$sql = "SELECT imagefile FROM imagedb";
$result = mysqli_query($con,$sql))
$row = mysqli_fetch_assoc($result);
echo $row['imagefile'];
?>
imagedb table has two columns:
'id' and 'imagefile' (type = LongBlob)
I am trying to read a rest api using php in the backend and React JS in the front end.
Here is my php code:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET');
header("Access-Control-Allow-Headers: X-Requested-With");
header('Content-Type: application/json');
$countryName = $_GET['countrystring'];
if (!empty($countryName)) {
$countryDataUrl =
'https://restcountries.eu/rest/v2/name/'.urlencode($countryName);
$countryDataJSON = file_get_contents($countryDataUrl);
$countryDataPHPArray = json_decode($countryDataJSON,true);
array_multisort($countryDataPHPArray);
$countryDataArrayLimited = array_slice($countryDataPHPArray, 0, 50);
echo json_encode($countryDataArrayLimited);
}
I have tried modifying header('Access-Control-Allow-Origin: *'); to header('Access-Control-Allow-Origin: http://localhost:3000');
My React code goes as follows:
import React, { Component } from 'react';
class Countrycomponent extends Component {
constructor(props) {
super(props);
this.state = {countrystring: this.props.countrystring,countries:[]};
}
componentDidMount(){
console.log("Enter");
fetch("http://localhost:8000/?countrystring="+ this.state.countrystring,{
method:'get',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
}).
then(response=>response.json()).
then(responseData=>{console.log(responseData)})
}
render() {
return (
<div className="">
<p>hello</p>
{this.state.countries.name}
</div>
);
}
}
export default Countrycomponent;
My react is running on port 3000 and the php on port 8000.
Thanks in advance.
Why do you need a PHP server when you can just do the following instead?
fetch("https://restcountries.eu/rest/v2/name/"+ this.state.countrystring,{
method:'get', .... )
I tested by making a request from Chrome console & restcountries.eu supports CORS request, so this should be fine
I am trying to send a single object from my angular 5 apllication to an php API in JSON format With HTTP POST, but i cant get it to work. I know this might be very basic but I am new to this topic and google cant help me or i am not searching the right keywords.
Errors:
1: With httpOptions parameter in data.service.ts -> http post method
2: Without httpOptions parameter in data.service.ts -> http post method
Line 55 in the php file is this one: $name=$_POST["name"]; I've also marked it in the file.
3: Network
I do not understand why i get the "405 not allowed Method Error" when i add a the Content-Type Header: application/json (Error 1). If i remove it the error wont show up but no data arrives at the API (Error 2).
The Content Type Header is set in the php file of the API. POST Method along other is also allowed in the php file.
I tested the API with the Restlet Client. it worked with Content-Type: application/x-www-form-urlencoded but also not with application/json:
json
x-www-form-urlencoded
What am I doing wrong?
Angular v5 -> package.json
Angularapp -> localhost:4200
API -> localhost:81 Apache
data.service.ts -> full File
const httpOptions = { headers: new HttpHeaders({ 'Content-Type':'application/json' })};
...
saveName(name: Name) {
const body = JSON.stringify(name.name);
return this.http.post('http://localhost:81/apitest/src/app/data/name.php', body, httpOptions);
}
API
<?php
// required headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTION");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
$connection = mysqli_connect('localhost', 'api', 'test', 'apitest');
$request_method = $_SERVER['REQUEST_METHOD'];
switch($request_method){
case 'GET':
if(!empty($_GET['nameId'])){
$nameId = intval($_GET['nameId']);
getNames($nameId);
} else {
getNames();
}
break;
case 'POST':
insertNames();
break;
case 'PUT':
updateNames();
break;
case 'DELETE':
deleteNames();
break;
default:
header('HTTP/1.0 405 Method Not Allowed');
break;
}
function insertNames()
{
global $connection;
$name=$_POST["name"]; // LINE 55 | Undefined index: name in [...] on line <b>55</b><br />
if(isset($_POST['name'])){
$query="INSERT INTO form SET name='{$name}'";
if(mysqli_query($connection, $query))
{
$response=array(
'status' => 201,
'status_message' =>'Name Added Successfully.'
);
}else
{
$response=array(
'status' => 400,
'status_message' =>'Name Addition Failed.'
);
}
}
else
{
$response=array(
'status' => 400,
'status_message' =>'Request Body Empty.'
);
}
header('Content-Type: application/json');
echo json_encode($response);
app.component.ts -> full File
saveName() {
this.dataService.saveName(this.name).subscribe(
data => {
this.getNames();
return true;
}, error => {
console.error('Failed');
}
);
}
HTML Form
<html>
<head>
<title>API TEST</title>
</head>
<body>
<form action="data/name.php" method="POST">
<label for="name">Name: </label>
<input type="text" name="name" [(ngModel)]="name.name">
{{name.name}}
<button name="post" (click)="saveName()">post</button>
</form>
</body>
</html>
did you try this?
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
$name = $obj['name']
from: Reading JSON POST using PHP
try to modify this, you missed S for OPTIONS method, and add HEAD method:
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, HEAD, OPTIONS");
When you invoke the CORS requests, the browser sends the OPTIONS request to the server to know what methods are allowed. This is so-called: Preflighted request