I have a form like this:
<form action="{{ route('admin.users.update', $user->id) }}" method="PUT" class="formajax_popup">
@csrf
@method('PUT')
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" value="{{ $user->name }}" class="form-control">
</div>
...
</form>
I automatically convert this form to ajax with a javascript class.Methods and values remain as they are.
This is the request I sent: Headers:
Request URL:
http://127.0.0.1:8000/admin/users/11
Request Method:
PUT
Status Code:
500 Internal Server Error
Remote Address:
127.0.0.1:8000
Referrer Policy:
strict-origin-when-cross-origin
HTTP/1.1 500 Internal Server Error
Host: 127.0.0.1:8000
Date: Fri, 02 Aug 2024 01:09:47 GMT
Connection: close
X-Powered-By: PHP/8.2.12
Content-type: text/html; charset=UTF-8
PUT /admin/users/11 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Content-Length: 783
Content-Type: application/x-www-form-urlencoded
Payload:
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="_token"
o9U1I2VBuhQvx6Zmcsl1wS98FcpP6XYHZkOtlbPD
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="_method"
PUT
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="name"
Duran Can YILMAZ
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="email"
[email protected]
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="password"
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="roles[]"
Super Admin
------WebKitFormBoundary1ouCYkAGCeExrdsT--
If I do request->all() in laravel, it naturally outputs this way.
array:1 [ // appHttpControllersAdminUserController.php:81
"------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition:_form-data;_name" => """
"_token"
o9U1I2VBuhQvx6Zmcsl1wS98FcpP6XYHZkOtlbPD
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="_method"
PUT
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="name"
Duran Can YILMAZ
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="email"
[email protected]
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="password"
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="undefined"
------WebKitFormBoundary1ouCYkAGCeExrdsT
Content-Disposition: form-data; name="roles[]"
Super Admin
------WebKitFormBoundary1ouCYkAGCeExrdsT--
"""
]
I am using Route::resource and the ajax package I wrote (https://github.com/duran004/FormAjax) so I don’t want to POST the form method. Because of HTTP standards. I want the form method to remain as PUT.
Does anyone have a solution other than parse the data?
Laravel route:
Route::resource('users', AdminUserController::class);
The javascript part sends it briefly like this:
submit(form) {
const formData = new FormData();
const formUrl = $(form).attr('action');
const formMethod = $(form).attr('method').toLowerCase();
const allElements = $(form).find(this.elementsSelector);
const checkboxNames = new Set();
var csrfInput = $(form).find('input[name="_token"]');
this.csrfToken = csrfInput.length ? csrfInput.val() : null;
const contentTypes = {
'post': 'application/json',
'put': 'application/x-www-form-urlencoded',
'delete': 'application/json',
'get': 'application/x-www-form-urlencoded'
};
this.log(`form_url: ${formUrl}
form_method: ${formMethod}
content_type: ${contentTypes[formMethod]}
csrf_token: ${this.csrfToken}`);
allElements.each((_, element) => {
const $element = $(element);
if ($element.is(':checkbox')) {
const name = $element.attr('name');
checkboxNames.add(name);
} else {
formData.append($element.attr('name'), $element.val());
}
});
checkboxNames.forEach(name => {
$(form).find(`input[name="${name}"]:checked`).each((_, el) => {
formData.append(name, $(el).val()); // Append each checked value
});
});
console.log(`form_data:`);
console.log(formData);
$.ajax({
url: formUrl,
method: formMethod,
data: formData,
processData: false, // Do not process data
// contentType: false, // Do not set content type
headers: {
'X-CSRF-TOKEN': this.csrfToken,
'Content-Type': contentTypes[formMethod]
},
success: (response, status, xhr) => {
console.log(response);
//if status start with 2
if (xhr.status.toString().startsWith('2')) {
if (response.status) {
this.handleSuccess(response);
} else {
this.handleError(response);
}
} else if (xhr.status.toString().startsWith('4')) {
this.handleError(response, 400);
} else if (xhr.status.toString().startsWith('5')) {
this.handleError(response, 500);
} else if (xhr.status.toString().startsWith('3')) {
this.handleError(response, 300);
} else if (xhr.status.toString().startsWith('1')) {
this.handleError(response, 100);
} else {
this.handleError(xhr);
}
},
error: (xhr) => this.handleError(xhr),
});
}
form_url: http://127.0.0.1:8000/admin/users/11
form_method: put
content_type: application/x-www-form-urlencoded
csrf_token: o9U1I2VBuhQvx6Zmcsl1wS98FcpP6XYHZkOtlbPD
According to https://datatracker.ietf.org/doc/html/rfc7231#section-4.3 standards, I want to implement put patch methods in laravel only with ajax.
What is expected is this: To send variables as it sends in the POST method. Or the variables can be easily parse on the laravel $request side.