PUT request from Backbone to Slim REST service causes 404 Not Found - php

I have a backbone script that calls a Slim REST service. GET requests are working fine, PUT requests are returning 404 Not Found. Note: this was working until my code was recently moved to a different server (and it works locally), so I'm guessing it has something to do with an Apache config setting. Here's a snippet of the backbone script:
jQuery(document).ready(function ($) {
//define box model
var Box = Backbone.Model.extend({
url: function () {
var urlId = (this.id) ? this.id : "";
var myUrl = "/wp-includes/api/service.php/box/" + urlId;
return myUrl;
}
});
var BoxView = Backbone.View.extend({
tagName: "div",
template: $("#boxTemplate").html(),
initialize: function () {
this.model = new Box(box);
this.render();
},
saveBox: function(e){
e.preventDefault();
$("#boxMessage").empty();
var formData = {},
prev = this.model.previousAttributes();
$(e.target).closest("form").find(":input").not("button").each(function (){
var el = $(this);
formData[el.attr("id")] = el.val();
});
this.model.set(formData);
this.model.save(
{ },
{
success: function() {
$("#boxMessage").html("Box information saved.");
},
error: function() {
}
}
);
}
Here's a snippet of the Slim REST service:
<?php
require 'Slim/Slim.php';
$app = new Slim();
$app->get('/workouts/:id', 'getWorkout');
$app->put('/box/:id', 'updateEventBox');
$app->run();
function getWorkout($id) {
echo json_encode(GetEventCompetitorWorkout($id));
}
function updateEventBox($id) {
$request = Slim::getInstance()->request();
$body = $request->getBody();
$eventBox = new EventBox(null);
$eventBox->TakeJson($body);
$eventBox->Save();
}
And here's the header info for the request:
Request URL:http://www.mydomain.com/wp-includes/api/service.php/box/1
Request Method:PUT
Status Code:404 Not Found
UPDATE: just tested a POST to the same service and it worked fine. PUT still fails.

I've found it not too uncommon that some servers only have GET,POST,HEAD enabled and that PUT,DELETE which are needed for REST are not enabled. That could be the case.
To test for this you can tell Backbone to use "emulatated HTTP" by calling this before your code:
Backbone.emulateHTTP = true;
This will make backbone use only GET/POST requests however it will append to the querystring "_method=PUT" or "_method=DELETE" which you can use on the serverside to detect the intended HTTP verb.
So on the server side you need to do something like this like as the first line of your index.php file (before any of the framework loads):
if (isset($_REQUEST['_method'])) $_SERVER['REQUEST_METHOD'] = $_REQUEST['_method'];

Related

Send POST data from NodeJs to PHP Symfony 5

I want to send POST data from NodeJS server (localhost:4000) to PHP symfony server (localhost:8000)
But every time when I'm trying to send it, I got always same result => empty array.
Here is my code:
NodeJS
var data = {
method: "disconnectFromGame",
};
var querystring = require("querystring");
var qs = querystring.stringify(data);
var qslength = qs.length;
var options = {
hostname: "http://localhost:8000",
port: 80,
path: "/game/api",
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': qslength
}
};
var buffer = "";
var req = http.request(options, function (res) {
res.on('data', function (chunk) {
buffer += chunk;
});
res.on('end', function () {
console.log(buffer);
});
});
req.write(qs);
req.end();
It works fine, debugger stop me at the specific breakpoint, so communication is OK, but $request has always empty parameters..
PHP Symfony 5
public function engineApi(Request $request) {
$user = $this->getUser();
if(!$user) {
return $this->redirectToRoute("app_login");
}
if (!$request->isXMLHttpRequest()) {
return $this->redirectToRoute("app_homepage_show");
}
$entityManager = $this->getDoctrine()->getManager();
$data = $request->request->all();
$api = new Api($data, $user, $entityManager);
return $api->processMethod();
}
Your script works :
How do you get the picture of your dump ? Because I think, this is where you made a mistake.
When you execute the NodeJs script, did you get a response from the Symfony server in your console ? Because if you put a dump() in your Symfony, you should have something like this (which is the raw view of html response with dump data from Symfony) :

Post form data to php script using axios

I'm trying to send the form data to a php script using axios.
Is the syntax of axios correct?
How can I view the data sent via the post method?
I just started programming in vuetify and php, so I need a little help
methods: {
formSubmit(e) {
e.preventDefault();
let currentObj = this;
this.axios.post('http://localhost/index.php/',{
name : this.name, user : this.username
})
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
},
}
in the php file there's :
<?php
require_once 'limonade.php';
$data = $_POST;
dispatch('/api/', 'test1');
function test1()
{
return 'Hello';
}
run();
Your php only acts when it's a GET Call, limonade's dispatch() is for GET only.
In your php you are creating a GET endpoint on the /api/ url that will execute the test1 function. Meaning when you call /api via get, you will get Hello as answer.
if you want that to be POST (without touching your javascript) the php should be something like:
# '/' because you are calling to http://localhost/index.php/ it could be '/whatever' if you call http://localhost/whatever (assuming you have configured everythign as limonade recomends)
function test2()
dispatch_post('/', 'test2');
{
return 'Hello via post';
}

Failed to load resource errors(405) when send Ajax data to php

I have error ->
"Failed to load resource: the server responded with a status of 405
(Method Not Allowed)"
when send Ajax data to PHP in larval.
(I made route)
Ajax code
function insertData()
{
var text = document.getElementById('humanText').value;
var user = document.getElementById('userName').innerText;
$.ajax({
type:"POST",
url: "insertContentData",
data:{text:text, user:user},
success: function(data){
alert(data);
}
});
document.getElementById('humanText').value = "";
};
insertData();
and my php code "insertContentData.php"
<?php
$data = $_POST['text'];
$user = $_POST['user'];
echo $data.", ".$user;
?>
why not work this?
Thanks for your help.
In the http world the "METHOD" normally used is "GET" which is simply pulling data from the server. When you want to send data from the user to the server you used "POST". These are the two most commonly used methods.
The errors says that the METHOD IS NOT ALLOWED. You are AJAX code shows that you are using the POST method.
In Laravel you need to define a route that allows for the POST method. So instead of Route::get($uri, $callback); it would be Route::post($uri, $callback); Some more information can be found in the Laravel Routing documentation. However I think you are missing some concepts based on the primitive PHP code you posted, that code should be inside a controller.
Try to run like this. I hope it works.
function insertData(){
var text = document.getElementById('humanText').value;
var user = document.getElementById('userName').innerText;
$.ajax({
type:"POST",
url: "insertContentData",
data:{text:text, user:user},
success: function(data){
alert(data);
}
});
document.getElementById('humanText').value = "";
};
window.onload = function(){
insertData();
}
<?php
$data = $_POST['text'];
$user = $_POST['user'];
echo $data.", ".$user;
?>

I'm getting a 406 response error when I try to make a https request (Note: no error when i use just http)

I'm using the cordova file-transfer plugin in order for users to upload pictures within my app.
My code works perfectly when making a normal http request to the php page on my server.
I would like to make a secure request so am trying to use https however I am getting a 406 error (see screenshot for error details)
All other ajax requests I am making within the app are working successfully using https.
I am currently not sending any headers when making the request however there is an option to do this using the file-transfer plugin.
I have looked into how I can solve this error (for example this question here) however am still uncertain as to what I need to do in my case.
I was wondering can you help determine what headers I need?
Here is my code:
Javascript
function uploadProfilePic(){
var token = localStorage.getItem("usertoken");
var defs = [];
var def = $.Deferred();
function win(r) {
if($.trim(r.response) === "0") {
alert("Sorry! We have encountered an error");
def.resolve(0);
}else{
def.resolve(1);
}
}
function fail(error) {
//upload of pic failed.
alert("Sorry! We have encountered an error: " + JSON.stringify(error));
def.resolve(0);
}
var uri = encodeURI("https://www.example.com/update_profile_pic.php");
var options = new FileUploadOptions();
options.fileKey="profile_pic_image_file";
options.mimeType="image/jpeg";
var params = new Object();
params.usertoken = token;
params.app_root_url = app_root_url;
//not sure what headers to add here.
//var headers={'headerParam':'headerValue'};
//options.headers = headers;
options.params = params;
var ft = new FileTransfer();
ft.onprogress = function(progressEvent){
if(progressEvent.lengthComputable){
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
}else{
loadingStatus.increment();
}
};
ft.upload($ESAPI.encoder().encodeForURL(profileImage), uri, win, fail, options);
defs.push(def.promise());
$.when.apply($, defs).then(function() {
//pic uploaded fine
});
}
PHP (upload_profile_pic.php)
header("Access-Control-Allow-Origin: *");
if(isset($_FILES['profile_pic_image_file'])){
$data['profile_image_is_set'] = true;
//do stuff with profile image here
echo json_encode($data);
}else{
$data['profile_image_is_set'] = false;
//image not set
echo json_encode($data);
}

Save API response to server as JSON file with AngularJS

I'm trying to create an app in AngularJS that aggregates data from multiple APIs. With some public APIs there are request limits and much of the data I want to pull is not updated very frequently, so only one request a month for a particular ID is necessary. To get past this, I've set up a Factory that first checks for a local file on the server, if it is not present, it then goes to the API and performs a GET request.
From there, once the request is complete, I want to save that file to the server with a name set by a field in the response.
I've found some examples using PHP with AngularJS but I'm not sure on how to save the JSON file with the dynamic name...or if this is even the best thing to do in order to avoid the request limits.
var apiUrl = 'https://example.com/api?userID=';
$http.get(apiUrl + $stateParams.userID).
success(function(data) {
$scope.content = data;
$scope.userID = data.userID
function(){
$http.post('saveJson.php', $scope.content).then(function() {
// log success
});
};
}).
error(function() {
// log error
});
PHP
<?php
$json = file_get_contents("php://input");
$file = fopen('/var/www/USERID.json','w+');
fwrite($file, $json);
fclose($file);
?>
If you do this in a service, and just call a method from a view button click, it would be more like this:
angular.module('app.services', [
])
.service('MyService', function ($http) {
var MyService = this;
this.aggregatedData = { content: [], filename: null };
this.apiUrl = 'https://example.com/api?userID=';
this.saveUrl = 'saveJson.php';
this.getData = function (url) {
return $http.get(url + $stateParams.userID).then(function (response) {
MyService.aggregatedData.content.push(response.data);
});
};
this.saveData = function (url, fileName) {
this.aggregatedData.filename = fileName;
return $http.post('saveJson.php', this.aggregatedData).then(function () {
// do something with the post response if desired
});
};
})
Then wire up buttons in your view to fetch and save by having the controller call the service methods.

Categories