I have a really strange bug.
In my local xampp's environment, the delete operation works great, the code is exactly the same, the database the same... And yet on hosting it doesn't work.
Code:
<!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <script src="//cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js"></script> <script src="https://cdn.datatables.net/1.10.9/js/dataTables.bootstrap.min.js"></script> <script src="https://cdn.datatables.net/responsive/2.0.0/js/dataTables.responsive.min.js"></script> <script> $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); </script> <script type="text/javascript"> var theGrid = null; $(document).ready(function(){ theGrid = $('#thegrid').DataTable({ "processing": true, "serverSide": true, "ordering": true, "responsive": true, "ajax": "http://eindeks.000webhostapp.com/przedmioties/grid", "columnDefs": [ { "render": function ( data, type, row ) { return '<a href="http://eindeks.000webhostapp.com/przedmioties/'+row[0]+'">'+data+'</a>'; }, "targets": 1 }, { "render": function ( data, type, row ) { return '<a href="http://eindeks.000webhostapp.com/przedmioties/'+row[0]+'/edit" class="btn btn-default">Zaktualizuj</a>'; }, "targets": 4 }, { "render": function ( data, type, row ) { return '<a href="#" onclick="return doDelete('+row[0]+')" class="btn btn-danger">Usuń</a>'; }, "targets": 4+1 }, ] }); }); function doDelete(id) { if(confirm('Naprawdę chcesz usunąć ten wpis?')) { $.ajax({ url: 'http://eindeks.000webhostapp.com/przedmioties/' + id, type: 'DELETE'}).success(function() { theGrid.ajax.reload(); }); } return false; } </script>
The same is on local's end (e.g. $.ajax({ url: 'http://localhost/dziennik/public/przedmioties/' + id, type: 'DELETE'})
)
But as you can see there is an Ajax with DataTables and it works well on both hosting and localhost.
But deletion doesn't work on my hosting's website.
Why? I don't know and I can't figure it out.
It's about this code I think:
function doDelete(id) { if(confirm('Naprawdę chcesz usunąć ten wpis?')) { $.ajax({ url: 'http://eindeks.000webhostapp.com/przedmioties/' + id, type: 'DELETE'}).success(function() { theGrid.ajax.reload(); }); } return false; }
But really, it's exactly the same (url different) on my localhost wherein which it is working. But on hosting it is not.
Okay, let's see the requests from the browser...
Localhost:
Yea, looks good, normal, and works. Nice!
But what on hosting?
What the... This is so weird. Just, I am looking at this and have no idea what is going on.
There is no response here:
And this xhr request has failed:
Ajax request is the same, code is the same, database is the same, both route ends working... I can't figure it out.
So what is the problem here?
5 Answers
Answers 1
It could very well be that your server is configured not to allow DELETE
requests or some of the other HTTP1.1+ verbs. In any case, HTML forms themselves don't allow PUT
, PATCH
, or DELETE
actions. While these should work in JavaScript, it is worth giving form method spoofing a try in your AJAX request. This will circumvent any configuration your server might have that would block such a request and also work whether you're using a form or AJAX.
If you're still not getting a response, you'll need to start debugging by looking through Apache access and error logs and eventually bubbling up to the framework if necessary.
Answers 2
1 - It might be that DELETE is disabled by the hosting provider. Ask the hosting provider whether DELETE is enabled. If you have access to apache check whether WebDAV module is enabled and if not, enable it.
2 - It might be CORS issue as well. Is CORS enabled on API. Send CORS headers with your request to API. barryvdh/laravel-cors is a great package for Laravel APIs for this purpose.
3 - Try changing type to POST and adding _method="DELETE" to the request. like this
$.ajax({ url: 'http://eindeks.000webhostapp.com/przedmioties/' + id, type: 'POST', data: {_method: 'delete'},
Answers 3
You need to approach the problem step by step. The first step is making sure that your server can receive the request properly. Whenever I need to do that, I use this code:
<?php header('Content-Type: application/json'); echo json_encode([ 'method' => $_SERVER['REQUEST_METHOD'], 'uri' => $_SERVER['REQUEST_URI'], 'body' => file_get_contents('php://input'), 'headers' => getallheaders(), ], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
Save the code as index.php and make a request to it. For instance, with curl:
curl -XDELETE http://example.com/index.php
If your server is working properly, you should get a response similar to this:
{ "method": "DELETE", "uri": "/index.php", "body": "", "headers": { "Host": "example.com", "User-Agent": "curl/7.53.1", "Accept": "*/*" } }
If not, then you know where the problem is.
Answers 4
Does your host allow DELETE
requests? I̶f̶ ̶n̶o̶t̶,̶ ̶y̶o̶u̶ ̶c̶o̶u̶l̶d̶ ̶r̶e̶f̶a̶c̶t̶o̶r̶ ̶y̶o̶u̶r̶ ̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶n̶d̶ ̶a̶d̶d̶ ̶a̶n̶ ̶a̶c̶t̶i̶o̶n̶ ̶p̶a̶r̶a̶m̶e̶t̶e̶r̶,̶ ̶f̶o̶r̶ ̶e̶x̶a̶m̶p̶l̶e̶,̶ ̶a̶n̶d̶ ̶̶P̶O̶S̶T̶
̶ ̶t̶h̶e̶ ̶r̶e̶q̶u̶e̶s̶t̶ ̶t̶o̶ ̶y̶o̶u̶r̶ ̶s̶e̶r̶v̶e̶r̶.̶ ̶ ̶ ̶
̶ ̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶s̶t̶o̶r̶e̶(̶R̶e̶q̶u̶e̶s̶t̶ ̶$̶r̶e̶q̶u̶e̶s̶t̶,̶ ̶$̶a̶c̶t̶i̶o̶n̶ ̶=̶ ̶'̶s̶t̶o̶r̶e̶'̶)̶ ̶{̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶i̶f̶ ̶(̶$̶a̶c̶t̶i̶o̶n̶ ̶=̶=̶=̶ ̶'̶s̶t̶o̶r̶e̶'̶)̶ ̶{̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶/̶/̶ ̶s̶t̶o̶r̶e̶ ̶n̶e̶w̶ ̶r̶e̶c̶o̶r̶d̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶}̶ ̶e̶l̶s̶e̶ ̶i̶f̶ ̶(̶$̶a̶c̶t̶i̶o̶n̶ ̶=̶=̶=̶ ̶'̶d̶e̶l̶e̶t̶e̶'̶)̶ ̶{̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶/̶/̶ ̶d̶e̶l̶e̶t̶e̶ ̶r̶e̶c̶o̶r̶d̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶ ̶}̶ ̶ ̶ ̶ ̶ ̶ ̶}̶
Edit: method spoofing
Answers 5
Try this code instead of the current yours on doDelete
function doDelete(id) { if (confirm('Naprawdę chcesz usunąć ten wpis?')) { $.ajax({ url: 'http://eindeks.000webhostapp.com/przedmioties/' + id, type: 'POST', data: {_method: 'delete'}, }).success(function() { theGrid.ajax.reload(); }); } return false; }
That will make laravel router go to the delete action without the need of support in the server of the DELETE verb.
0 comments:
Post a Comment