I have an API built with PHP Slim Framework 3 and testing the API with Postman everything is working great but when I put the app on the server and tried to make an Ajax Call I've got this message:
Failed to load https://api.mydomain.net/usuario/autenticar?xAuthClienteID=2&xAuthChaveApi=3851b1ae73ca0ca6e3c24a0256a80ace&login=admin&senha=teste: Redirect from 'https://api.maydomain.net/usuario/autenticar?xAuthClienteID=2&xAuthChaveApi=3851b1ae73ca0ca6e3c24a0256a80ace&login=admin&senha=teste' to 'https://api.mydomain.net/404.html' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
I've looked up Slim docs on how to enable CORS on my server and applied it on the function I use to return JSON. It looks like this:
public function withCustomJson($meta = null, $data = null)
{
if (isset($data)) {
$finalResponse['data'] = $data;
}
$finalResponse['meta'] = array(
'status' => (isset($meta['status']) ? $meta['status'] : null),
'message' => (isset($meta['message']) ? mb_convert_encoding($meta['message'], "UTF-8", "auto") : null)
);
$response = $this->withBody(new Body(fopen('php://temp', 'r+')));
$response->body->write($json = json_encode($finalResponse));
// Ensure that the json encoding passed successfully
if ($json === false) {
throw new \RuntimeException(json_last_error_msg(), json_last_error());
}
//Allowing CORS as Slim docs states
$responseWithJson = $response->withHeader('Content-Type', 'application/json;charset=utf-8')
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
if (isset($meta['codStatus'])) {
return $responseWithJson->withStatus($meta['codStatus']);
}
return $responseWithJson;
}
And here's what my Ajax call looks like:
<script type="text/javascript">
try {
$.ajax({
url: 'https://api.mydomain.net/usuario/autenticar',
type: 'GET',
dataType: 'json',
data: {
xAuthClienteID:'2',
xAuthChaveApi: '3851b1ae73ca0ca6e3c24a0256a80ace',
login: 'admin',
senha: 'teste'
},
ContentType: 'application/json',
success: function(response){
console.log(response);
},
error: function(err){
console.log(err);
}
});
}
catch(err) {
alert(err);
}
</script>
So, what am I doing wrong? Appreciate any help.
Related
I'm trying to make an http post request in ionic with php on backend,..
Here's my code in ionic :
let body = {
'data': ['data [0]', 'data [1]']
};
let options = {
headers : { 'Content-Type' : 'application/json' }
};
const ifSuccess = (response) => {
console.log(response);
this.data = response;
};
const ifFail = (response) => {
this.error = 'Oops! Une erreur au niveau du serveur...';
};
this.http.post('http://localhost/cantine-itu/test', body, options).subscribe(ifSuccess, ifFail);
Here's the backend (in php flight) :
Flight::before('json', function () {
header('Access-Control-Allow-Origin: http://localhost:8100');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET,PUT,POST,DELETE');
header('Access-Control-Allow-Headers: *');
});
Flight::route('POST /test', function(){
$data = Flight::request()->data;
Flight::json($data);
});
I'm getting an error saying that : Access to XMLHttpRequest at 'http://localhost/cantine-itu/test' from origin 'http://localhost:8100' 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.
(error-image)
Are you getting this error from web browser or a particular device?
Since this is local development and not production I would set to the most permissive possible.
'capacitor://localhost',
'ionic://localhost',
'http://localhost',
'http://localhost:8080',
https://ionicframework.com/docs/troubleshooting/cors
After hours of trying is still can't get my React Expo application (localhost http://192.168.1.113:19006/#/) to connect to my PHP api that is hosted on an external server.
The header of my api file's is as following;
header("Access-Control-Allow-Origin: *");
//header("Access-Control-Allow-Headers: *");
//header("Access-Control-Allow-Credentials: 'true'");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
When I use postman to connect and test mine /login.php file with the following json body;
POST to: www.URLofAPIlocation.nl/subFolder/api/login.php
{
"email" : "info#email.nl",
"password" : "Password12345"
}
The api returns the JWT token and succes message as expected.
{
"message": "Successful login.",
"jwt": "eyJ0eXA..... ( FULL TOKEN )"
}
But when I try to connect with the following functions within my react native application it try to uses the localhost base url and not the given;
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'cors', // Without cors it fails.
cache: 'no-cache',
// credentials: 'same-origin', // Not sure if needed.
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Max-Age':' 3600',
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify(data)
});
return await response.json();
}
// https://www.URLofAPIlocation.nl/... and https://URLofAPIlocation.nl/ also not working
function login(){
postData('www.URLofAPIlocation.nl/subFolder/api/login.php', {
email : "info#email.nl",
password : "Password12345",
})
// Other option without error catching. (not working..)
// .then((data) => {
// console.log(data); // JSON data parsed by `response.json()` call
// });
.then(response => {
console.log(response)
return response.json()
})
.then(response => {
console.log("End query"+ response);
return response;
})
.catch(err => {
console.log("Error: "+err)
});
}
I'm not sure what I do wrong since every tutorial and documentation I find the exact same setup as I am using.
The error message is as following;
POST http://192.168.1.17:19006/www.URLofAPIlocation.nl/subFolder/api/login.php 404 (Not Found)
It seems like that react expo uses it's own location as the base url and adds the url of the fetch after it. The location of the api is off course without: http://192.168.1.17:19006//. I can't find where to change or remove this, so help would much be appreciated.
Thanks in advance!
Ps because of personal reasons I've hidden the exact web address of the api location and passwords. The api is hosted on an https domain and functions as expected.
In my laravel app there is a zip file in my public path I want to download it using ajax not return zip file and throw an error which shown in image anybody help to solve this problem thanks in advance.
$files = glob(public_path('uploads/download-images'));
\Zipper::make(public_path('uploads/product_images.zip'))->add($files)->close();
return response()->download(public_path('uploads/product_images.zip'));
this is ajax
var join_selected_values = allVals.join(",");
$.ajax({
url: $(this).data('url'),
type: 'POST',
data:'_token = <?php echo csrf_token() ?>',
data: 'ids='+join_selected_values,
success: function (data)
{
window.location = data;
alert('Seccussfully Downloaded');
},
error: function (data) {
alert(data.responseText);
}
});
I'm not sure but this might have something to do with you having to set header configuration for the response. You have to change the content-type to your desired one of course. I hope it helps.
{
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, PATCH, DELETE',
'Access-Control-Allow-Headers' => 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Authorization , Access-Control-Request-Headers',
'Content-Type' => 'application/pdf'
];
return response()->download(filepathHere, nameHere, $headers);
}
Also make sure:
Symfony HttpFoundation, which manages file downloads, requires the file being downloaded to have an ASCII file name.
From my understanding you can't return a download response using Ajax calls. The work around is, don't use an ajax request to download. Just do a traditional request. Because it returns a download response, the browser will automatically open the download dialog, so it will be similar to a no refresh.
Cors working in this api users/login problem in postjob/store api i solved this issue adding cors true in angular.
After few days i call this api again same error occur
XMLHttpRequest cannot load http://192.168.10.5/jobpost1/public/api/job. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9001' is therefore not allowed access.
Routes.php
Route::group(['prefix' => 'api'], function () {
Route::post('users/login', array('middleware' => 'Cors', 'uses' => 'Auth\AuthController#login'));
});`
Route::group(['prefix'=>'api'], function()
{
Route::group(['middleware'=>'jwt-auth'], function ()
{
Route::post('postjob/store', array('middleware' => 'Cors', 'uses'=> 'PostController#store'));
});
});
Cors.php
class Cors
{
public function handle($request, Closure $next)
{
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Origin'=> '*',
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin',
'Access-Control-Allow-Credentials' => 'true'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}
angular code
return $http({
method: 'POST',
url: 'http://192.168.10.4/jobpost1/public/api/job',
cors: true,
xhrFields: {
withCredentials: true
},
params: {
"token" :token,
"user_id": userId,
"job_shift": job_shift,
"job_type": job_type,
"job_description":job_description,
"degree_title": degree_title,
"city": city,
"experience": experience,
"career_level": career_level,
"gender":gender,
"total_position": total_position,
"minimum_edu":minimum_edu,
"apply_before": apply_before
}
}).then(function successCallback(response, status) {
callback(response, status);
debugger;
}
, function errorCallback(response, status) {
callback(response, status);
debugger;
});
};
Rather than adding headers using foreach:
foreach($headers as $key => $value)
$response->header($key, $value);
Give this a go instead:
$response->headers->add($headers);
I am using laravel as backend and angujarjs as frontend to make an application. The frontend is sitting in another server, and therefore I have to deal with cross domain policy. I have enabled CORS, so I can "send" post request.
The problem is that when I am trying to get Input::all() in laravel, the request gets cancelled. (status shown 'cancelled' in Chrome network). But when I dont use Input, everything is OK.
//laravel
class SessionController extends BaseController {
protected $entity;
public function __construct(SessionEntity $entity)
{
$this->entity = $entity;
}
public function getLogin()
{
return Response::json('hello')->header('Access-Control-Allow-Origin', '*');
}
public function postLogin()
{
//$data = Input::all();
//return Response::json($data);
// $user = $entity->login($data);
// if($user)
// {
// return Response::json($user);
// } else {
// return Response::json($entity->errors(), 400);
// }
//the code below is OK (able to send response back) , but the code above is not, because I am using Input::all()
$data = array(
"email" => "324234",
"password" => "654321"
);
return Response::json($data);
}
}
//angularjs
.controller('LoginController', ['$scope', '$http', function($scope, $http) {
$scope.send = function(credential) {
$http({
method: 'POST',
url: 'http://localhost:8000/api/session/login',
data: credential,
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
})
.success(function(data, status, headers) {
console.log(data);
console.log(status);
console.log(headers);
});
};
}]);
Here's the headers to enable CORS
App::after(function($request, $response)
{
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
$response->headers->set('Access-Control-Max-Age', '1728000');
$response->headers->set('Content-Type', 'application/json; charset=UTF-8');
return $response;
});
What did I miss??
I found it. I use namespace but didn't include 'use Input'.
silly me...
Also, I found that I have to explicitly set Content-Type to 'application/json' in order to receive data using Input::all() in laravel, otherwise I get no data.
For cross domain requests you must use jsonp instead json