有没有办法从 PHP 脚本中达到 API 端点但保留原始请求方法?
Posted
技术标签:
【中文标题】有没有办法从 PHP 脚本中达到 API 端点但保留原始请求方法?【英文标题】:is there a way to hit an API end point from a PHP script but retain the original request method? 【发布时间】:2020-01-12 19:44:12 【问题描述】:根据这个answer,
...
header("Location: ...")
设置一个状态码,显式导致浏览器使用 GET 请求,而不是它使用的任何方法。
这正是我正在编写的应用程序所看到的行为,该应用程序试图通过 API 将数据添加到数据库中。
我希望旁边有红线的那一行也说 POST。
这是调用 makeAPIcalls.php 文件中 API 端点的逻辑:
# read raw data from request body and stuff it into $_POST
$_POST = json_decode(file_get_contents('php://input'), true);
# set variables using data that was passed in
$id = getParameterValue('id');
// there are others that aren't shown here
# make API call depending on request method
$method = $_SERVER['REQUEST_METHOD'];
$url = 'http://localhost:8080/miscellaneous/APIexamples/CRUD/';
if ($method == 'GET') $url .= 'mobile/list';
if ($method == 'POST') $url .= 'mobile/add';
if ($method == 'PUT') $url .= 'mobile/edit/' . $id;
if ($method == 'DELETE') $url .= 'mobile/remove/' . $id;
header('Location: ' . $url);
是否有替代 header('Location: '...
的方法来访问保留原始请求方法的 API 端点?
编辑: 这是表格和JS:
<form action="" method="post" id="add">
<legend>Add Mobile</legend>
<ol>
<li>
<label for="add_name">name</label>
<input type="text" name="name" id="add_name"></input>
</li>
<li>
<label for="add_model">model</label>
<input type="text" name="model" id="add_model"></input>
</li>
<li>
<label for="add_color">color</label>
<input type="text" name="color" id="add_color"></input>
</li>
</ol>
<button type="button" onclick="addMobile()">Submit</button>
<button type="reset">Cancel</button>
</form>
function addMobile()
// get the form data
var formData =
name: $('#add input[name="name"]').val(),
model: $('#add input[name="model"]').val(),
color: $('#add input[name="color"]').val()
// process form
$.ajax(
method:"POST",
url:"js/makeAPIcalls.php",
contentType: 'application/json',
data: JSON.stringify(formData),
async: true,
cache: false
)
.done(function(data)
// log data to console for visibility
// console.log(data);
// clear out form fields
$('#add input[name="name"]').val('');
$('#add input[name="model"]').val('');
$('#add input[name="color"]').val('');
)
.fail(function(data)
console.log(data);
console.log('AJAX call failed');
)
【问题讨论】:
如果您需要 client(浏览器)来发起 POST 请求,那么您不能为此使用重定向。页面上带有method="POST"
的表单可以解决问题,如果需要,您可以通过 javascript 自动提交。
我正在使用 AJAX 添加数据以避免在用户单击提交时重新加载页面。
客户端 AJAX 跟随重定向,仍然作为另一个 AJAX 请求?在这种情况下,不用重定向响应,而是用数据响应,并让 AJAX 响应处理程序向 API 提交 AJAX POST。
@David - 太棒了!我将删除 makeAPIcalls.php 脚本并将所有 URL 直接放在 AJAX 中。
【参考方案1】:
如果这不是为了简洁起见而简化的示例,并且这确实是makeAPIcalls.php
中的所有服务器端代码,那么首先甚至不需要这种交互。客户端已经知道进行 API 调用所需的一切:
$.ajax(
method:"POST",
url:"http://localhost:8080/miscellaneous/APIexamples/CRUD",
/.../
)
.done(function(data)
$('#add input[name="name"]').val('');
$('#add input[name="model"]').val('');
$('#add input[name="color"]').val('');
)
不需要与服务器的来回、重定向等。
【讨论】:
它可以完全删除makeAPIcalls.php
脚本并替换.ajax
中对它的引用,如下所示:url: 'http://localhost:8080/miscellaneous/APIexamples/CRUD/mobile/add'
。
@knot22: 哦,如果整个事件序列根本不需要任何服务器端交互(在调用makeAPIcalls.php
之前,客户端已经知道一切)那肯定会更好.我会更新答案。
@David 重定向并不总是 GET 请求。另见:***.com/a/42138726/362536【参考方案2】:
返回307
或308
状态码是告诉客户他们应该在新位置重复整个请求的正确方法。
307
用于临时重定向,308
用于永久重定向。
【讨论】:
所有主流浏览器都支持,很开心。 caniuse.com/#search=307caniuse.com/#search=308以上是关于有没有办法从 PHP 脚本中达到 API 端点但保留原始请求方法?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法让 Swashbuckle 将 OData 参数添加到 Web API 2 IQueryable<T> 端点?