当Ext JS从restful商店发出DELETE请求时,它包含一个实体主体.虽然HTTP规范似乎没有禁止这样做,但Google App Engine不接受此类请求.所以我想知道是否有办法阻止Restful商店在DELETE请求中包含冗余实体主体.
细节:
使用此示例作为参考:http: //www.sencha.com/deploy/dev/examples/restful/restful.html
这就是商店的定义方式:
var store = new Ext.data.Store({
id: 'user',
restful: true, // <-- This Store is RESTful
proxy: proxy,
reader: reader,
writer: writer
});
Run Code Online (Sandbox Code Playgroud)
按下"删除"按钮后,这是Ext JS发送的请求:
DELETE http://www.sencha.com/deploy/dev/examples/restful/app.php/users/6 HTTP/1.1
Host: www.sencha.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pt-BR; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/json; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://www.sencha.com/deploy/dev/examples/restful/restful.html
Content-Length: 10
Cookie: bb_sessionhash=8d75f5e42d576fb695a02bf1d24c9ff1; …Run Code Online (Sandbox Code Playgroud) 我正在构建一个REST API.实际上我理解了共同的指导和规则.
但我有DELETE方法的问题,因为我需要在请求中通过正文发送数据,DELETE方法将忽略正文.
如果你问什么数据让我通过DELETE方法将它发送到身体,是一个'url'和一些其他参数.当然'url'在数据库中有id,所以我可以使用DELETE没问题,比如DELETE https://api.example.com/content/url:url_id.但是,通过id,我选择传递它自己和其他一些参数的URL.我的业务逻辑和要求迫使我传递url而不是DELETE方法中的id.
所以在阅读之后,我发现还有一些代理阻塞DELETE和PUT方法.并且HTML表单仅支持GET和POST方法.
我开始思考,更好地只使用GET和POST在我的REST API.所以我可以使用POST进行删除和对象或资源,如下所示:
POST /content/delete/url
Body :
url : xxxx
param1 : xxxx
param2 : xxx
Run Code Online (Sandbox Code Playgroud)
但是在"REST API设计规则手册,O'reilly"中,第18页说
"应该使用HTTP请求方法来指示执行哪个CRUD功能"
以下反模式举例说明了不该做的事情:
Run Code Online (Sandbox Code Playgroud)GET /deleteUser?id=1234 GET /deleteUser/1234 POST /users/1234/delete
在再次搜索和阅读之后,我找到了一些解决方案
运用 X-HTTP-Method-Override
使用api方法名称,如闪烁(api.flickr.com/services/rest/?method=flickr.collections.getInfo)和mailchimp(api.mailchimp.com/1.3/?method=campaignDelete)
我想我喜欢解决方案1,使用'X-HTTP-Method-Override'.你怎么看?
谷歌似乎使用X-HTTP-Method-Override,对此https://developers.google.com/gdata/docs/2.0/basics
Flicker和Mailchimp使用方法名称,如解决方案2中所示
所以我查看了这篇文章: 是一个允许http删除请求的实体
这似乎表明,虽然在某些概念层面上做"好",但在实践中它可能不可行,因为浏览器只是忽略它.
我有一些express.js身份验证中间件我需要通过,我不想将我的用户详细信息附加到url params.我需要进行身份验证的所有其他请求都会将这些详细信息附加到请求正文中.
有没有办法强迫这个?我看到其他一些帖子,其中有些人似乎成功通过删除请求传递了一个正文.
我正在运行一个节点/ sails后端.它始终将正文记录为未定义的删除请求.有没有办法修改
有没有其他人能够用CFHTTP删除purge_everything?我似乎无法通过ColdFusion CFHTTP成功清除CloudFlare区域的缓存.但我能够做其他事情,如列表区等.所以我知道我可以成功CFHTTP到CloudFlare的API.
这是curl命令,有效:
curl -svX DELETE -H 'X-Auth-Email: a@b.c' -H 'X-Auth-Key: XYZ' https://api.cloudflare.com/client/v4/zones/xxxxxxx/purge_cache -H 'Content-Type: application/json' --data '{"purge_everything":true}'
Run Code Online (Sandbox Code Playgroud)
返回的错误是:
{"success":false,"errors":[{"code":1012,"message":"请求必须包含\"purge_everything \"或\"files \"或\"tags"}],"消息 ":[]," 结果":空}
我尝试了很多代码组合......这些是我尝试过的不同变量:
<cfset stFields = '{"purge_everything":true}'>
<cfset stFieldsJson = {"purge_everything":true}>
<cfset stFieldsJson2 = {
"fields" : {
"purge_everything" : true
}
}>
<cfset stFieldsJson3 = {
"purge_everything" : true,
"fields" : {
"purge_everything" : true
}
}>
<cfset tmp = {} />
<cfset tmp['purge_everything'] = true />
Run Code Online (Sandbox Code Playgroud)
......这里是我做过的一些不同的电话组合......
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare" charset="utf-8">
<cfhttpparam type="header" name="X-Auth-Email" value="a@b.c"> …Run Code Online (Sandbox Code Playgroud) import { Injectable } from '@angular/core';
import { Http, Response,Headers,RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/Rx';
import{Router} from'@angular/router';
import 'rxjs/add/operator/map';
@Injectable()
export class ManageJobDeleteService{
constructor(private http: Http,private router:Router){};
DeleteRequestToAPI(post_jobs_id:string){
let body = JSON.stringify({post_jobs_id:post_jobs_id});
let headers = new Headers({ 'Content-Type': 'application/json'});
let options = new RequestOptions({ headers: headers });
console.log(body);
console.log(options);
return this.http.delete('http://127.0.0.1:8000/api/employer/post_jobs/',body,options)//HERE I AM GETTING ERROR
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response){
let body = res.json();
console.log(body);
return body || [];
}
private handleError …Run Code Online (Sandbox Code Playgroud) 我正在使用expressjs和body-parser中间件.
这就是我发起它的方式:
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Run Code Online (Sandbox Code Playgroud)
从客户端我发送DELETE请求,当我尝试从服务器端提取它时,我得到一个空对象:
app.delete('/', function(req, res) {
console.log(util.inspect(req.body)); //outputs {}
//some more code
});
Run Code Online (Sandbox Code Playgroud)
但是当我发送POST时,我得到了我需要的东西:
app.post('/delete', function(req, res) {
console.log(util.inspect(req.body)); //outputs { mid: 'ffw1aNh2' }
//some more code
});
Run Code Online (Sandbox Code Playgroud)
值得注意的是,我没有在客户端更改任何内容(angularjs),但方法和url以及firefox网络调试器显示在两种情况下发送的数据.
这里缺少什么?为什么我在删除方法上获得一个空体对象?
发布到 aspnetcore api 时,我收到 415 http 错误结果。如果我的端点标记为 [HttpPost] 而不是 [HttpDelete],则不会发生这种情况
在 aspnetcore api 控制器中:
[HttpDelete]
public async Task<IActionResult> Delete([FromBody]EntityViewModel vm)
{
Run Code Online (Sandbox Code Playgroud)
在角度控制器中:
var obj = new Object();
obj.atr1 = 1;
obj.atr2 = 2 ;
$http.post(route, obj)
.then(function (response) {
Run Code Online (Sandbox Code Playgroud)
实体视图模型.cs
public class EntityViewModel
{
public int Atr1 { get; set; }
public int Atr2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud) 我有这样配置的标准angular $ resource
angular.module('client.resources')
.factory('ProjectSubjectResource',['$resource',
function ($resource) {
release: {
method: 'DELETE',
isArray: false
}
});
}]);
Run Code Online (Sandbox Code Playgroud)
我称这种方法为
ProjectSubjectResource.release({projectId: projectId, subjectId: 0},{ subjectIds: subjectIdArray})
Run Code Online (Sandbox Code Playgroud)
其中subjectIdArray是对象数组:
[{subject1: 213123}, {subject2: 3131}]
Run Code Online (Sandbox Code Playgroud)
但是,请求主体不包含该数组.我怀疑DELETE请求是问题,因为重命名方法调用例如PUT有所不同.
我可以以某种方式允许DELETE请求的主体吗?
假设有人PUT对我的Endint 执行请求:
/resources/{id}
Run Code Online (Sandbox Code Playgroud)
但是我的PostgreSQL数据库中没有存储具有给定ID的资源。
根据RFC 2616,如果我能够执行以下操作,则应创建资源:
该
PUT方法请求将封闭的实体存储在提供的Request-URI下。如果Request-URI引用了已经存在的资源,则应将封闭的实体视为驻留在原始服务器上的实体的修改版本。如果Request-URI没有指向现有资源,并且请求用户代理能够将该URI定义为新资源,则原始服务器可以使用该URI创建资源。
可以使用提供的ID创建资源吗?由于在数据库插入上手动分配ID并不是最佳实践。
如果404无法创建资源,是否应该返回错误?
我正在使用Java Jersey 2.17构建RESTful Web服务.客户端.我正在使用ExtJS 5进行开发.
我的服务课程
Main.java
public class Main
{
public static final String BASE_URI = "http://localhost:8080/app/rest/";
public static HttpServer startServer() {
final ResourceConfig rc = new ResourceConfig();
rc.packages(true, "app");
rc.register(ResponseCorsFilter.class);
return GrizzlyHttpServerFactory.createHttpServer(URI.create(Main.BASE_URI), rc);
}
public static void main(final String[] args) throws IOException {
final HttpServer server = Main.startServer();
System.out.println(String.format("Jersey app started with WADL available at " + "%sapplication.wadl\nHit enter to stop it...",
Main.BASE_URI));
System.in.read();
server.stop();
}
}
Run Code Online (Sandbox Code Playgroud)
UserRi.java
@Path("/user")
public class UsersRi {
@DELETE
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String …Run Code Online (Sandbox Code Playgroud) rest ×6
angularjs ×3
ajax ×2
http-delete ×2
angular ×1
angular6 ×1
api ×1
api-design ×1
asp.net-core ×1
body-parser ×1
cfhttp ×1
cfml ×1
cloudflare ×1
coldfusion ×1
express ×1
extjs ×1
grizzly ×1
http ×1
java ×1
jersey-2.0 ×1
node.js ×1
php ×1
put ×1
sails.js ×1
typescript ×1