我最近看到许多框架决定"伪造"PUT和DELETE请求.就像Ruby on Rails一样.他们似乎在等待浏览器赶上来.他们在等待是徒劳的吗?
这甚至可以在任何地方实施吗?
我想知道我目前的方法是否有意义,或者是否有更好的方法来做到这一点.
我有多种情况,我想创建新对象,让服务器为这些对象分配一个ID.发送POST请求似乎是最合适的方法.但是,由于POST不是幂等的,因此请求可能会丢失并再次发送它可能会创建第二个对象.由于API通常通过移动网络访问,因此丢失请求可能非常普遍.
结果我决定将整个过程分成两个步骤.首先发送POST请求以创建新对象,该对象返回Location头中新对象的URI.其次,对提供的位置执行幂等PUT请求,以使用数据填充新对象.如果在24小时内未填充新对象,则服务器可能会通过某种批处理作业将其删除.
这听起来合理还是有更好的方法?
谢谢
不应该使用PUTCreate和POST,Update因为PUT是幂等的.
这样,同一个订单的多个PUT只会放置一个订单?
这一直困扰着我一段时间......我正在构建一个RESTful API,在某些情况下必须接收文件.
使用时HTTP POST,我们可以阅读data from $_POST和files from $_FILES.
使用时HTTP GET,我们可以阅读data from $_GET和files from $_FILES.
但是,在使用时HTTP PUT,AFAIK读取数据的唯一方法就是使用了php://input stream.
一切都很好,直到我想通过HTTP PUT发送文件.现在php://输入流不再按预期工作了,因为它也有一个文件.
这是我目前如何读取PUT请求的数据:
(只要没有发布文件,它就能很好用)
$handle = fopen('php://input', 'r');
$rawData = '';
while ($chunk = fread($handle, 1024)) {
$rawData .= $chunk;
}
parse_str($rawData, $data);
Run Code Online (Sandbox Code Playgroud)
当我输出rawData时,它显示
-----ZENDHTTPCLIENT-44cf242ea3173cfa0b97f80c68608c4c
Content-Disposition: form-data; name="image_01"; filename="lorem-ipsum.png"
Content-Type: image/png; charset=binary
?PNG
???...etc etc...
???,
-----ZENDHTTPCLIENT-8e4c65a6678d3ef287a07eb1da6a5380
Content-Disposition: form-data; name="testkey"
testvalue
-----ZENDHTTPCLIENT-8e4c65a6678d3ef287a07eb1da6a5380
Content-Disposition: form-data; name="otherkey"
othervalue
Run Code Online (Sandbox Code Playgroud)
有谁知道如何通过HTTP …
我正在实现RESTful API,我不确定"社区接受"行为是否存在无法更改的数据.例如,在我的API中有一个"文件"资源,在创建时包含许多在创建后无法修改的字段,例如文件的二进制数据,以及与之关联的一些元数据.此外,'文件'可以有书面描述和相关标签.
我的问题涉及对这些"文件"资源之一进行更新.特定"文件"的GET将返回与文件关联的所有元数据,描述和标签,以及文件的二进制数据.特定"文件"资源的PUT是否应包含"只读"字段?我意识到它可以用任何一种方式编码:a)包括PUT数据中的只读字段,然后验证它们与原始数据匹配(或发出错误),或b)忽略PUT数据中只读字段的存在因为它们无法更改,如果它们不匹配或丢失则永远不会发出错误,因为逻辑会忽略它们.
似乎它可以采用任何一种方式并且可以接受.忽略只读字段的第二种方法可以更紧凑,因为API客户端可以跳过发送只读数据(如果需要); 这对那些知道自己在做什么的人来说似乎很好......
我正在尝试使用requests模块重写一些旧的python代码.目的是上传附件.邮件服务器需要以下规范:
https://api.elasticemail.com/attachments/upload?username=yourusername&api_key=yourapikey&file=yourfilename
Run Code Online (Sandbox Code Playgroud)
有效的旧代码:
h = httplib2.Http()
resp, content = h.request('https://api.elasticemail.com/attachments/upload?username=omer&api_key=b01ad0ce&file=tmp.txt',
"PUT", body=file(filepath).read(),
headers={'content-type':'text/plain'} )
Run Code Online (Sandbox Code Playgroud)
没有找到如何在请求中使用正文部分.
我设法做了以下事情:
response = requests.put('https://api.elasticemail.com/attachments/upload',
data={"file":filepath},
auth=('omer', 'b01ad0ce')
)
Run Code Online (Sandbox Code Playgroud)
但不知道如何使用文件内容指定正文部分.
谢谢你的帮助.奥马尔.
更确切地说:
根据休息样式,通常认为POST,GET,PUT和DELETE http方法应该用于CREATE,READ,UPDATE和DELETE(CRUD)操作.
事实上,如果我们坚持使用http方法定义,事情可能就不那么清楚了
在本文中,它解释了:
简而言之:当且仅当您知道资源所在的URL以及资源的全部内容时才使用PUT.否则,请使用POST.
主要是因为
PUT是一个限制性更强的动词.它需要一个完整的资源并将其存储在给定的URL中.如果之前有资源,则将其替换; 如果没有,则创建一个新的.这些属性支持幂等性,天真的创建或更新操作可能不支持.我怀疑这可能是为什么PUT的定义方式; 它是一种幂等操作,允许客户端向服务器发送信息.
在我的情况下,我通常会发布传递所有资源数据的更新,因此我可以使用PUT进行更新,但每次发出更新时,我都会保存一个LastUser和LastUpdate列,其中包含进行修改的用户ID和操作的时间.
所以我想知道你的意见,因为严格来说,这两列并不是资源的一部分,但它们确实阻止了操作是幂等的.
saludos
SAS
我在我的路线中有这个:
+--------+---------------------------+--------------+--------------------------- ---------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+---------------------------+--------------+--------------------------- ---------+----------------+---------------+
| | GET|HEAD / | | postcontroller | auth | |
| | GET|HEAD login | | homecontroller@dologin | | |
| | POST login | | homecontroller@dologin | | |
| | GET|HEAD logout | | homecontroller@dologout | | |
| | GET|HEAD post | post.index | postcontroller@index | | |
| | GET|HEAD post/create | post.create | postcontroller@create …Run Code Online (Sandbox Code Playgroud) 我能够成功运行以下curl命令(在命令行中):
curl -XPOST --basic -u user:password -H accept:application/json -H Content-type:application/json --data-binary '{ "@queryid" : 1234 }' http://localhost/rest/run?10
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所做的事情,但它似乎没有使用我正在使用的REST服务:
$headers = array(
'Accept: application/json',
'Content-Type: application/json',
);
$url = 'http://localhost/rest/run?10';
$query = '{ "@queryid" : 1234 }';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "user:password");
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
curl_setopt($ch, CURLOPT_POSTFIELDSIZE, strlen($query));
$output = curl_exec($ch);
echo $output;
Run Code Online (Sandbox Code Playgroud)
尝试使用PUT方法转换--data-binary时,正确的方法是什么?
我正在尝试通过SSL发出请求.证书已安装在计算机上,可通过浏览器运行.
我正在使用此请求:
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] data = encoding.GetBytes(request.Content.OuterXml.ToString());
string password = "XXXX";
X509Certificate2 cert = new X509Certificate2("c:\\zzzz.p12", password);
string key = cert.GetPublicKeyString();
string certData = Encoding.ASCII.GetString(cert.Export(X509ContentType.Cert));
Uri uri = new Uri(request.Url);
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(uri);
myRequest.Credentials = new NetworkCredential(request.User, request.Password.ToString());
myRequest.Method = "PUT";
myRequest.ContentType = request.ContentType;
myRequest.ContentLength = data.Length;
myRequest.ClientCertificates.Add(cert);
Stream newStream = myRequest.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
System.IO.StreamReader st = new StreamReader(((HttpWebResponse)myRequest.GetResponse()).GetResponseStream());
Run Code Online (Sandbox Code Playgroud)
使用此代码我收到此错误:
底层连接已关闭:无法为SSL/TLS安全通道建立信任关系.---> System.Security.Authentication.AuthenticationException:根据验证程序,远程证书无效.
问题是什么?