Cannot send HTML string through axios - laravel

I'm working on a blog like website and have being adding this rich text editor feature to it. This app is built with Vue for the front and Laravel, and this text editor is a dependency called vue-quill.
I use axios to post all the data and nothing more. Im using it to create posts with Raw html tags from this editor, it actually works fine creating and updating posts locally, but only fails on my server whenever you try to update any post, it returns empty response and status 200.
It does not happen when you create a post. Im not using any kind of image upload service but I'm using my own solution, which consists on transforming images from base 64 to file objects and then send them to a controller via axios. On update action it is similar but the images that were already uploaded on the post are fetched, then converted to base64 again and then converted to file objects again (in order to preserve previous images) for new images I convert them from base64 to file object as I do on my create action.
Here is the code I use to create from base 64 to file object :
dataURLtoFile(dataurl, filename) {
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
}
And this would be my axios action:
axios
.post("/api/posts", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((response)=>{
this.submit = false;
this.title= '';
this.showAlert("success", 'Post created successfully.' , '')
})
.catch((error) =>{
// etc
});
The formData object only store the raw html, images and a string, nothing more than that, but I'm not sure if the headers of the axios are ok, the laravel action is like this:
public function updatePost(Request $request)
{
$request->validate([
'files.*' => 'required|mimes:jpg,jpeg,png|max:2048'
]);
$post = Post::find($request->postId);
$images = $request->file('files');
// creamos el post primero
$post->title = $request->title;
$post->body = $request->body;
$post->save();
// the rest of the code for storing images
return response()->json(['post' => $post]);
I think something is preventing it to reach to this action, because the response is empty.
Edit: I had a problem later where the request was giving status 301, after searching here and there I found out that everything was okay but in the server. The host has to be configured as stated here in this quick guide for 301 troubles : https://medium.com/#mshanak/laravel-return-empty-response-690f8a308d9a.

Related

Cannot send file from Postman to Laravel API

I am trying to send an image to my laravel APIs from postman.
I added the file(280KB) on the request body like so:
On the server side I am trying to catch the file and save it, but it returns that there is no file.
public function uploadImage(Request $request)
{
//returns false
$request->hasFile('profile_image');
//returns profile_image is required
$request->validate(['profile_image' => 'required|image:jpeg,png,jpg,gif,svg']);
//returns null
$request->file('profile_image');
}
I am calling the function from api.php like so:
Route::put('/creators/{id}/upload_image',[CreatorController::class,'uploadImage']);
I thought maybe I shouldn't put the file in Body, but couldn't find an alternative.
Also I am finally trying to send the file from a vue client, but I had the same Issue when trying to send the file from there.
How do I get the server to catch the file?
Edit: adjusted typo in example code
new code sample
I changed the method from put to post, since I wanted to test the post method as well. I also tried _method put in postman beforehand.
Here is the code sample on Laravel:
//api.php
Route::put('/creators/{id}/upload_image',[CreatorController::class,'uploadImage']);
//CreatorController.php
public function uploadImage(Request $request)
{
if($request->hasFile('profile_image')){
$allowedfileExtension=['gif','jpg','png'];
$file = $request->file('profile_image');
$extension = $file->getClientOriginalExtension();
if(in_array($extension,$allowedfileExtension)) {
$path = $file->store('public/images/profile');
$path_url = $path;
return ["image_url" => $path_url, "image" => $request->file('profile_image')];
}
return false;
}
}
The $request->hasFile('profile_image') returns true, but then $request->file('profile_image') returns null, failing to save the image.
My vue client side code (if it might turn useful):
if(this.profile_image != null){
let data = new FormData();
data.append('profile_image', this.profile_image)
axios
.post('http://localhost:8000/api/creators/'+uid+'/upload_image', data, head)
.then(
response => (
//successfully receives the image_url
this.creatorData.image_url = response.data.image_url,
console.log(response.data)
),
)
.catch(
error => (
localStorage.setItem('error', error),
console.log(error.response)
),
this.loading = false,
)
}
The client side actually receives the "image_url" but the image is not saved on laravel.
laravel dose not support put method directly.
you must use post method then pass _method to your laravel project
like this picture

How can I get the signature image from this signature pad with Vuejs + Laravel

Hi I have this signtaure pad with Vuejs:
Signature pad code
I am trying to send this data into a controller to store it, but when I do this:
const { isEmpty, data } = this.$refs.signaturePad.saveSignature();
console.log(isEmpty);
console.log(data);
let formData = new FormData();
formData.append('signtaure', this.$refs.signaturePad.saveSignature());
axios.post('/api/employee/update/27141399-8?api_token='+App.apiToken, formData, config)
.then(function (response) {
currentObj.success = response.data.success;
})
If I check the console.log() it displays this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABioAAAJxCAYAAADcoOoFAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3c+LrUmaF/AYN25GqkXGndbIbEQYSxQUV+WAi9lIzT8g1S5ddbkQXAhVsxSErlq7qGpcupgqcCHCYNfGhQhjLcQfMM604CC6GAsFR8Fp+eL7jNGnT96b92bmiXif83khOXnvPXki4vNEZla93xMRPzNcBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFFAj+zqF3NEiBAgAABAgQIECBAgAABAgQIECBAgAABAgSGoMIkIECAAAECBAgQIECAAAECBAgQIECAAAECBJYJCCqW0WuYAAECBAgQIECAAAECBAgQIECAAAECBAgQEFSYAwQIECBAgAABAgQIECBAgAABAgQIECBAgMAyAUHFMnoNEyBAgAABAgQIECBAgAABAgQIECBAgAABAoIKc4AAAQIECBAgQIA
I check the laravel controller to get the file like this:
$request->signature;
And it is empty.. a blank value so I wonder how can I send the base_64 image with vuejs to the controller because how I am doing it does not work
You append the signature to the formdata object like this:
formData.append('signtaure', this.$refs.signaturePad.saveSignature());
In the laravel controller you're checking for the signature property on the request object.
Notice the typo you've made within the append function? signtaure != signature.
#julianstark999 also made a comment about this, but I think you misinterpreted his comment, so I'm explaining it again :)

Why Laravel API request sent from Vue gets canceled

I'm trying to send formData from Vue using Axios to Laravel (v6) API on Laravel Homestead containing some data and an excel file to read and validate data in the backend. If the sheet contains records than 800 for example everything works file but when I increased it to 850 or 1000 the request gets cancelled I don't know why.
Successful request
Cancelled request
As you see it doesn't reach the actual request like the successful request it just gets cancelled at the beginning.
But the weird thing is that the data got validated and inserted into the DB already but the response gets converted to cancelled and the actual success response doesn't get returned from the API
Is this error related to server configurations or needs code fix?
Vue code
submitImportedUsers(){
let formData = this.gatherFormData();
this.importUsers(formData);
},
gatherFormData() {
//create formData to send normal dta with files
let formdata = new FormData();
formdata.append("users", this.form.usersFile);
formdata.append("images", this.form.imagesFile);
const json = JSON.stringify({
unique_fields: this.form.uniqueFields,
update_duplicates: this.form.duplicateUsers,
entity_id: this.entityId,
user_id: this.userId,
});
formdata.append("data", json);
return formdata;
Laravel
$usersImportService->moveFile($request->file('users'));
public function moveFile($file) {
if(is_null($this->folderName) || !isset($this->folderName)){
$this->generateUuid();
}
$ext = $this->getRequestFileExt($file);
$usersFileName = $this->folderName.'.'.$ext;
$this->fileName = $usersFileName;
$path = storage_path().'/uploads';
\File::isDirectory($path) or \File::makeDirectory($path, 0777, true, true);
move_uploaded_file($file->getRealPath(), $this->storePath.$usersFileName);
}
Then start reading it using Laravel Excel and insert the data into the database
I found the issue which the front end developer did in axios instance that might help anyone facing this issue
axiosInstance.defaults.timeout = 10000;
It could be anything like that used to set the timeout of axios it's set to 10 seconds here and the request needs more time so setting this to a higher value solved the issue

Laravel Api returns Html instead of json

Hello there my website is on cpanel and when i make an api call it returns contnet-type html instead of json note that it worked perfectly on my localhost but for some reason it isn't working
Code
public function fetch_companies()
{
//getting company that is linked to coupon
$companies_id = Coupons::where('company_id' , '!=', 'null')->pluck('company_id');
$companies = Companies::whereIn('id' , $companies_id)->get();
return response()->json($companies);
}
i tried setting the headers to json like this
return response()->json($companies)->withHeaders([
'Content-Type' => 'application/json',
]);
but it didn't work
here is the link to my website you may test it using postman
http://coupon-app.epizy.com/company/api/fetch
just to put you in the picture the code currently running this page is this
public function fetch_companies()
{
//getting company that is linked to coupon
$companies_id = Coupons::where('company_id' , '!=', 'null')->pluck('company_id');
$companies = Companies::whereIn('id' , $companies_id)->get();
return response()->json($companies)->withHeaders([
'Content-Type' => 'application/json',
]);
}
if you need any information please comment and Thanks in Advance
well i found out that the cause of this problem was my server provider as you can find here
https://infinityfree.net/support/javascript-error-using-api-or-mobile-android-app/
it is a security "feature" although it is not a feature that blocks any request that doesn't accept cookies and run javascript
Change Accept & Content-Type to Application/json on the header

simple json response with cakephp

I trying to pass some json to a controller in cakePHP 2.5 and returning it again just to make sure it is all going through fine.
However I getting no response content back. Just a 200 success. From reading the docs I am under the impression that if I pass some json then the responseHandler will the return json as the response.
Not sure what I am missing.
Data being passed
var neworderSer = $(this).sortable("serialize");
which gives
item[]=4&item[]=3&item[]=6&item[]=5&item[]=7
appController.php
public $components = array(
'DebugKit.Toolbar',
'Search.Prg',
'Session',
'Auth',
'Session',
'RequestHandler'
);
index.ctp
$.ajax({
url: "/btstadmin/pages/reorder",
type: "post",
dataType:"json",
data: neworderSer,
success: function(feedback) {
notify('Reordered pages');
},
error: function(e) {
notify('Reordered pages failed', {
status: 'error'
});
}
});
PagesController.php
public function reorder() {
$this->request->onlyAllow('ajax');
$data = $this->request->data;
$this->autoRender = false;
$this->set('_serialize', 'data');
}
UPDATE:
I have now added the following to the routes.php
Router::parseExtensions('json', 'xml');
and I have updated my controller to
$data = $this->request->data;
$this->set("status", "OK");
$this->set("message", "You are good");
$this->set("content", $data);
$this->set("_serialize", array("status", "message", "content"));
All now works perfectly.
A proper Accept header or an extension should to be supplied
In order for the request handler to be able to pick the correct view, you need to either send the appropriate Accept header (application/json), or supply an extension, in your case .json. And in order for extensions to be recognized at all, extension parsing needs to be enabled.
See http://book.cakephp.org/...views.html#enabling-data-views-in-your-application
The view only serializes view vars
The JSON view only auto-serializes view variables, and from the code you are showing it doesn't look like you'd ever set a view variable named data.
See http://book.cakephp.org/...views.html#using-data-views-with-the-serialize-key
The view needs to be rendered
You shouldn't disable auto rendering unless you have a good reason, and in your case also finally invoke Controller:render() manually. Currently your action will not even try to render anything at all.
CakeRequest::onlyAllow() is for HTTP methods
CakeRequest::onlyAllow() (which btw is deprecated as of CakePHP 2.5) is for specifying the allowed HTTP methods, ie GET, POST, PUT, etc. While using any of the available detectors like for example ajax will work, you probably shouldn't rely on it.
Long story short
Your reorder() method should look more like this:
public function reorder() {
if(!$this->request->is('ajax')) {
throw new BadRequestException();
}
$this->set('data', $this->request->data);
$this->set('_serialize', 'data');
}
And finally, in case you don't want/can't use the Accept header, you need to append the .json extension to the URL of the AJAX request:
url: "/btstadmin/pages/reorder.json"
and consequently enable extension parsing in your routes.php like:
Router::parseExtensions('json');
ps
See Cakephp REST API remove the necessity of .format for ways to use the JSON view without using extensions.
Output your json data
public function reorder() {
$this->request->onlyAllow('ajax');
$data = $this->request->data;
$this->autoRender = false;
$this->set('_serialize', 'data');
echo json_encode($data);
}

Resources