I'm using Vue.js and Laravel in combination with Axios to make a search filter for my records. When I make the request, I get the following error in my console.
GET http://localhost:8000/api/quests/search/?keywords=test 405 (Method
Not Allowed)
Vue.js
export default {
data() {
return {
quests: [],
quest: {
id: '',
name: '',
price: '',
},
keywords: null,
}
},
watch: {
keywords(after, before) {
this.fetchSearch();
}
},
methods : {
fetchSearch() {
axios.get('/api/quests/search', { params: { keywords: this.keywords}}, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => console.log(res.data))
// data empty
.catch(error => console.log(error));
}
}
API route
Route::get('quests/search', 'CrudsController#search');
Controller
public function search(Request $request)
{
$quests = Quest::where('name', 'like', $request->keywords)->get();
return QuestResource::collection($quests);
}
Network response
Cache-Control: no-cache, private
Connection: close
Content-Type: application/json
Date: Mon, 03 Dec 2018 16:08:05 +0000
Date: Mon, 03 Dec 2018 16:08:05 GMT
Host: localhost:8000
X-Powered-By: PHP/7.2.10
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
What am I doing wrong here?
You might be missing csrf token.
Try adding it to your header
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
Or you could alternatively exclude this route vie adding it to $exclude array on csrf middleware.
Related
I'm running a PHP server on command line with
php -S localhost:8000 index.php
and the contents of the server are
<?php
require 'vendor/autoload.php';
use Embed\Embed;
$embed = new Embed();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
flush();
ob_flush();
echo $_POST;
print($_POST);
var_dump($_POST);
// Prepare the response
$response = [
'status' => 'success',
'message' => 'why does this not reach you',
];
// Return the response as JSON
echo json_encode($response);
} else {
// Return an error response if the request method is not POST
$response = [
'status' => 'error',
'message' => 'Invalid request method. POST request expected.',
];
echo json_encode($response);
}
?>
The command line does react when requests come in like so:
[Fri Feb 3 18:11:47 2023] PHP 8.2.1 Development Server (http://localhost:8000) started
[Fri Feb 3 18:11:48 2023] 127.0.0.1:54363 Accepted
[Fri Feb 3 18:11:48 2023] 127.0.0.1:54363 Closing
but it says "Closing" almost immediately after the request comes in, and I can't get the contents of the request to print using echo, print, or var_dump. The client does get a response back but it looks like garbage:
{"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "A4EEE117-0E46-46B3-9BA9-519F6B27357B", "name": "Unknown", "offset": 0, "size": 0, "type": "text/html"}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "A4EEE117-0E46-46B3-9BA9-519F6B27357B", "name": "Unknown", "offset": 0, "size": 0, "type": "text/html"}}, "bodyUsed": false, "headers": {"map": {"connection": "close", "content-type": "text/html; charset=UTF-8", "date": "Sat, 04 Feb 2023 02:07:35 GMT", "host": "localhost:8000", "x-powered-by": "PHP/8.2.1"}}, "ok": true, "status": 200, "statusText": "", "type": "default", "url": "http://localhost:8000/"}
And I'm sending the request with React Native:
9 function getThumbnail(url){
8 fetch('http://localhost:8000/', {
7 method: 'POST',
6 headers: {
5 'Accept': 'application/json',
4 'Content-Type': 'application/json',
3 },
2 body: JSON.stringify({
1 data: url
0 })
1 })
2
3 .then((response) => {
4 console.log(response);
5 })
6 .catch((error) => {
7 console.error("got an error");
8 console.error(error);
9 });
10 }
I'm not sure what's going on because the server receives the request but doesn't seem to get any data from it, closes the connection immediately, and sends back a response that looks like garbage. Also haven't done much with PHP before so sorry if I'm missing something super basic.
I tried changing the server to print the contents of GET requests with print(implode($_GET)) and to navigate to localhost:8000 in my browser, but the contents of $_GET are empty as well:
Received GET request:
Looks like you are sending raw json data
Try something like this
$body = json_decode(file_get_contents('php://input'), true);
print_r($body );
I'm trying to get a JSON from my local php server into a ionic 4 application. First I discovered that I had to use "ionic cordova emulate browser" instead of "ionic serve" command in order to make HTTP work, since cordova is required. After this, I could reach a JSON example from jsonplaceholder website, but I still can't reach my local server. I tried all possible combinations of urls for my local server and I have no clue what to do next. The codes:
tab1.module.ts
import { Component } from '#angular/core';
import { HTTP } from '#ionic-native/http/ngx';
import { Tab1Service } from '../api/tab1/tab1.service'
#Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
//v: requests from my local server
v1: any;
v2: any;
v3: any;
v4: any;
v5: any;
//a: requests from other server
a1: any;
a2: any;
constructor(public http: HTTP, public tab1Service:Tab1Service) {
//My server
//With HTTP -------------
//Set v1
this.http.get('http://192.168.0.21/WebServer/Ionic/process.php', {}, {})
.then(res => {
this.v1 = res.data;
}
)
.catch(err =>
this.v1 = err
);
//Set v2
this.http.get('192.168.0.21/WebServer/Ionic/process.php', {}, {})
.then(res => {
this.v2 = res.data;
}
)
.catch(err =>
this.v2 = err
);
//Set v3
this.http.get('http://localhost/WebServer/Ionic/process.php', {}, {})
.then(res => {
this.v3 = res.data;
}
)
.catch(err =>
this.v3 = err
);
//Set v4
this.http.get('localhost/WebServer/Ionic/process.php', {}, {})
.then(res => {
this.v4 = res.data;
}
)
.catch(err =>
this.v4 = err
);
//With HttpClient ---------------
//Set v5
this.tab1Service.getConfig()
.subscribe((data) => this.v5 = data['dados']);
//Other server
//With HTTP -------------
//Set a1
this.http.get('https://jsonplaceholder.typicode.com/todos/1', {}, {})
.then(res => {
this.a1 = res.data;
}
)
.catch(err =>
this.a1 = err
);
//With HttpClient ---------------
//Set a2
this.tab1Service.getConfig2()
.subscribe((data) => this.a2 = data['title']);
}
}
PS: All the urls combinations work in the browser
tab1.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class Tab1Service {
constructor(private http: HttpClient) {}
getConfig() {
return this.http.get('http://192.168.0.21/WebServer/Ionic/process.php');
}
getConfig2() {
return this.http.get('https://jsonplaceholder.typicode.com/todos/1');
}
}
process.php
<?php
$result = "{ \"success\": true, \"dados\": \"teste\" }";
//Echo $result and set headers
echo $result;
header("Access-Control-Allow-Credentials: true");
header("Content-Type: application/json; charset=utf-8");
PS: I have the same problem with and without these headers
Prints:
Tab One page: I print all the variables in the same order that they appear in tab1.module.ts in Tab One Page (I created the ionic tab project)
JSON output from both servers
Response Headers from both servers
Console error output when setting v5: This error seems to be related to HttpClient function
Versions:
PHP 7 with Apache Lounge
Ionic 4.10.3
Cordova 8.1.2
Everything I did was based on internet tutorials since I'm pretty new to ionic and php.
EDIT 1
The images information as text:
Tab One page output (Vs {{v1}}, {{v2}}, {{v3}}, {{v4}}, {{v5}} | As {{a1}}, {{a2}})
Vs
[object Object],
[object Object],
[object Object],
[object Object], |
As
{ "userId": 1, "id": 1, "title": "delectus aut autem", "completed":
false },
delectus aut autem
JSON from both servers
My server
{ "success": true, "dados": "teste" }
jsonplaceholder
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Response Headers from both servers
My server
Access-Control-Allow-Credentials: true
Connection: Keep-Alive
Content-Length: 37
Content-Type: application/json; charset=utf-8
Date: Tue, 19 Mar 2019 14:55:59 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.38 (Win64) PHP/7.3.3
X-Powered-By: PHP/7.3.3
jsonplaceholder
Access-Control-Allow-Credentials: true
Cache-Control: public, max-age=14400
CF-Cache-Status: HIT
CF-RAY: 4ba06d22bfc3ba18-ATL
Connection: keep-alive
Date: Tue, 19 Mar 2019 15:19:43 GMT
Etag: W/"53-hfEnumeNh6YirfjyjaujcOPPT+s"
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-
cgi/beacon/expect-ct"
Expires: Tue, 19 Mar 2019 19:19:43 GMT
Pragma: no-cache
Server: cloudflare
Vary: Origin, Accept-Encoding
Via: 1.1 vegur
X-Content-Type-Options: nosniff
X-Powered-By: Express
Console error
ERROR {…} error: errorbubbles: falsecancelBubble: falsecancelable: false
composed: (...) message: "Http failure response for
http://192.168.0.21/WebServer/Ionic/process.php: 0 Unknown Error" name:
"HttpErrorResponse"ok: falsestatus: 0 statusText: "Unknown Error" url:
"http://192.168.0.21/WebServer/Ionic/process.php"
EDIT 2
Guys, I found what was wrong with my request. The Access-Control-Allow-Origin header was missing. So, when I added:
header("Access-Control-Allow-Origin: *");
in the end of process.php, it worked.
EDIT 3
IMPORTANT: I've just learned that if you add this header you actually put your server in risk, since it becomes more vulnerable to CSRF attack and other similar attacks. So, the right thing to do is to add the specific origins that need to access the server and not use * as a value for Access-Control-Allow-Origin header.
I have coded a API with laravel on a subdomain called backend.example.com. If I try to get informations from my API from another subdomain called partner.example.com I have no problems to verfiy myself and get those informations. This is the Ajax request:
This is the Ajax for the main domain:
var ajaxArray = {
"fromDate": from,
"toDate": to
};
console.log(ajaxArray);
jQuery.ajax({
url: ("https://backend.example.com/api/v1/leads/showAdmin"),
type: "POST",
data: ajaxArray,
crossDomain: true,
headers : {
"Authorization": "Basic " + btoa("api#example.com" + ":" + "123456"),
"Accept": "application/json"
},
error: function() { alert("Error"); },
success: function(result){
alert("Working");
});
}});
And this is my Ajax request from the subdomain which is wokring:
var ajaxArray = {
"fromDate": from,
"toDate": to,
"table": "no",
"userID": 20
};
console.log(ajaxArray);
jQuery.ajax({
url: ("https://backend.example.com/api/v1/leads/show"),
type: "POST",
data: ajaxArray,
crossDomain: true,
headers : {
"Authorization": "Basic " + btoa("api#example.com" + ":" + "123456"),
"Accept": "application/json"
},
error: function() { alert("No"); },
success: function(result){
alert("Working");
});
}});
But if I am trying to do exactly the same with the main domain called example.com I get this error:
Failed to load https://backend.example.com/api/v1/leads/showAdmin:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://example.com' is therefore not allowed access.
The question I am asking my self is why because I have allowed all ....
See here:
<?php
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedOriginsPatterns' => [],
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'],
'exposedHeaders' => [],
'maxAge' => 0,
];
Would appreciate any kind of help!
Kind regards
UPDATE:
This is my response and request header:
General:
Request URL:https://backend.example.com/api/v1/leads/showAdmin
Request Method:OPTIONS
Status Code:200
Remote Address:94.130.239.164:443
Referrer Policy:no-referrer-when-downgrade
Response Header:
allow:POST
cache-control:private, must-revalidate
content-length:0
content-type:text/html; charset=UTF-8
date:Mon, 05 Mar 2018 13:52:41 GMT
expires:-1
pragma:no-cache
server:nginx
status:200
x-powered-by:PleskLin
x-powered-by:PHP/7.2.2
Request Header:
:authority:backend.example.com
:method:OPTIONS
:path:/api/v1/leads/showAdmin
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
access-control-request-headers:authorization
access-control-request-method:POST
origin:https://example.com
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
And this is the Laravel Cors Library I am using:
https://github.com/asm89/stack-cors
All settings I have done regarding the Cors Library is above.
Hello I try to do a web application and I have a problem.
When I request the token from /oauth/token I receive this response:
{"error":"unsupported_grant_type","message":"The authorization grant type is not supported by the authorization server.","hint":"Check the `grant_type` parameter"}
And my code is:
import { Injectable } from '#angular/core';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
#Injectable()
export class UserService {
private API: string = 'api/';
private OAuth: string = 'oauth/'
constructor(private _HTTP: Http) { }
private get_header(): RequestOptions {
let headers = new Headers();
headers.append('Access-Control-Allow-Origin', '*' );
headers.append('Content-Type', 'application/x-www-form-urlencoded' );
return new RequestOptions({ headers: headers });
}
Signin(email: string, password: string): void {
let data = {
form_params: {
grant_type: 'password',
client_id: 2,
client_secret: 'vSFxVqALQHjyotPyGfhrGj3ziudUGsts2ZWiAGms',
username: email,
password: password,
scope: '*',
}
};
this._HTTP.post(
this.OAuth + 'token',
data,
this.get_header()
).toPromise()
.then( (_response) => {
console.log (_response);
});
}
}
And the request header:
POST /oauth/token HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8000/signin
Access-Control-Allow-Origin: *
Content-Type: application/json
X-XSRF-TOKEN: eyJpdiI6IkxtOHhqd0RDUW9MVjl1YVh0U0c4N2c9PSIsInZhbHVlIjoiUmdrenlLWll2eEFtdGFQK2dsWGN0Nm5jWGY2MW5HXC9zMDJFdU52SEh4RUoxSkY1QWVHUFNySXFkUUQ3SDNaTW0zNll6SVRONlFHQjBFVzZPT0RxQkR3PT0iLCJtYWMiOiIwNzg5ZjliMzUwYjE5ZWM4MWE3MTg3NDRjYWZiMDE1MWI1NWJjN2E1NmI5ZTMzY2UzMTIwODI4ODY0ZDQ1ZDY5In0=
Content-Length: 208
Cookie: XSRF-TOKEN=eyJpdiI6IkxtOHhqd0RDUW9MVjl1YVh0U0c4N2c9PSIsInZhbHVlIjoiUmdrenlLWll2eEFtdGFQK2dsWGN0Nm5jWGY2MW5HXC9zMDJFdU52SEh4RUoxSkY1QWVHUFNySXFkUUQ3SDNaTW0zNll6SVRONlFHQjBFVzZPT0RxQkR3PT0iLCJtYWMiOiIwNzg5ZjliMzUwYjE5ZWM4MWE3MTg3NDRjYWZiMDE1MWI1NWJjN2E1NmI5ZTMzY2UzMTIwODI4ODY0ZDQ1ZDY5In0%3D; laravel_session=eyJpdiI6ImlrdlNMTGtTK241WVArZGx6MzE5Mnc9PSIsInZhbHVlIjoiRVQxSmlpZFwvV3B4eVRHVUdVYlRtY1VOZHUzZ09FQnMyZjhjSnZoQjA0VVBvM0x5YnJJbmx3b25cL3dCbVZScTVUb2lTVkg5Sldyd3R0aFluMDBvcmhxQT09IiwibWFjIjoiZDk4NjZkMDhiNTE0NzA3YzQxODVkNGJjN2E3OTRjNWEzMjc2Njk2ZjEyODY2MzY3NmRhYzAzN2U1NGE0ZTg4NCJ9
Connection: keep-alive
Response header:
HTTP/1.1 400 Bad Request
Host: localhost:8000
Connection: close
x-powered-by: PHP/7.1.1
Content-Type: application/json
Cache-Control: no-cache, private
Date: Thu, 27 Jul 2017 09:35:53 +0000, Thu, 27 Jul 2017 09:35:53 GMT
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Post data:
{
"form_params": {
"grant_type": "password",
"client_id": 2,
"client_secret": "vSFxVqALQHjyotPyGfhrGj3ziudUGsts2ZWiAGms",
"username": "fasfa",
"password": "fasfa",
"scope": "*"
}
}
I don't have any other detail.
You need to install a password client for Passport. Assuming you've installed and configured Passport, to generate a password client, run:
php artisan passport:client --password
Make sure to use the details from the output of this command in your API requests.
inside form-data in postman use following
grant_type : password
client_id : 2
client_secret : vSFxVqALQHjyotPyGfhrGj3ziudUGsts2ZWiAGms or whatever this is
username: myemail#yahoo.com
password: mypassword
scope:
You can get client id and secret from oauth_clients table if no data there use following command to create a client
php artisan passport:client --password
use the oauth_clients table particular row, where password client column value is 1
see how i have integrated token generation code with login. I used right format to solve grant issue in laravel 5.8
public function login(Request $request) {
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
if(Auth::check()) { // check whether user exist
$req = Request::create('/oauth/token', 'POST',[
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => 'WDv6wrY9Tf9HuixaiQjDWGy7yBqEG1IrmsLucAUI',
'username' => request('email'),
'password' => request('password'),
'scope' => ''
]);
$res = app()->handle($req);
$responseBody = json_decode($res->getContent()); // convert to json object
return response()->json(['success' => $responseBody], $res->getStatusCode());
} else {
return response()->json(['error' => 'Not logged in '], 401);
}
} else {
return response()->json(['error' => 'Authentication failed '], 401);
}
}
I used the following request on Fiddler, it worked fine :
check the header Content-Type:
'Content-Type': 'application/json'
I have a PHP script that makes query to DB and returns the result as JSON data. This file contains some Codeigniter specific functions.
This functions recieve id and returns back to the JS code some data from a table.
public function get_l($id){
//$id is not empty variable
$this->db->where('id',$id);
$q=$this->db->get('news');
$res = $q->result_array();
$this->output->set_header("HTTP/1.0 200 OK");
$this->output->set_header("HTTP/1.1 200 OK");
$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate");
$this->output->set_header("Cache-Control: post-check=0, pre-check=0");
$this->output->set_header("Content-Type: application/json; charset=utf-8");
$this->output->set_header("Pragma: no-cache");
$out = json_encode($res);
$this->output->set_output($out);
}
And then I need to process that JSON with the next JS code:
function getContent(id){
$.post('/admin_ajax/news/get',
{
id: id
},
function(result)
{
alert(result+"\n"+result.length);//this will output [object Object] 1
for (var key in result)
{
alert(key+':'+result[key]); //and this 0:[object Object]
}
alert(result.title); //here we are getting undefined
},
'json'
);
I am not receiving errors or warnings in console. And in the firebug I see what was returned from the server.
HTTP headers:
Server nginx/1.1.19
Date Fri, 26 Oct 2012 11:59:12 GMT
Content-Type application/json; charset=utf-8
Content-Length 85
Connection keep-alive
X-Powered-By PHP/5.3.10-1ubuntu3.4
Cache-Control post-check=0, pre-check=0
Pragma no-cache
And response:
[{"id":"5","title":"test","alias":"test","content":"tes","date":"123","type":"test"}]
JSON:
alias "test"
content "tes"
date "123"
id "5"
title "test"
type "test"
I found a similar question here but it wasn't helpful.
Your JSON object is in an array [...] hence the length 1.
function(result) {
var jsonObj = result[0];
It seems like the response you are getting is actually an array with one element (the json object).
Try using result[0], like so:
....
function(result)
{
alert(result[0]+"\n"+result[0].length);//this will output [object Object] 1
for (var key in result[0])
{
alert(key+':'+result[0][key]); //and this 0:[object Object]
}
alert(result[0].title); //here we are getting undefined
}
....
Result is an array with one element:
[
{
"id": "5",
"title": "test",
"alias": "test",
"content": "tes",
"date": "123",
"type": "test"
}
]
The element at index 0 contains the information you need. You need to do:
alert(result[0].id);
alert(result[0].title);
alert(result[0].alias);