【问题标题】:Grails 'method not allowed' weirdnessGrails'方法不允许'怪异
【发布时间】:2013-08-09 20:27:34
【问题描述】:

我有简单的控制器代码,例如:

// UserController.groovy

class UserController {

    static allowedMethods = [
            signIn:       'GET',
            authenticate: 'POST',
            signOut:      'POST',
            register:     'GET',
            save:         'POST'
    ]

    // ... code omitted

    def register() { }

    def save() {
        render 'ok'
    }
}

注册表:

<!-- register.gsp -->
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="layout" content="main" />
    <title>Withme: Register</title>
</head>
<body>
    <g:form mapping="register">
        <!-- Code omitted -->
        <g:actionSubmit value="Register" />
    </g:form>
</body>
</html>

还有 url 映射:

//UrlMappings.groovy

class UrlMappings {
    static mappings = { 
        name register: '/register'(controller: 'user') {
            action = [GET: 'register', POST: 'save']
        }
    }
}

现在是奇怪的部分。当使用 curl 发出请求时,一切都按预期工作:

$ curl http://localhost:8080/withme/register -X GET -v -L
... form rendered ...

$ curl http://localhost:8080/withme/register -X POST -v -L
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Transfer-Encoding: chunked
< Date: Thu, 08 Aug 2013 07:41:23 GMT
< 
* Connection #0 to host localhost left intact
ok* Closing connection #0 

使用浏览器访问 /register 会返回表单。但是当我在浏览器中提交时,返回 405!

HTTP Status 405 -

type Status report

message

description The specified HTTP method is not allowed for the requested resource.
Apache Tomcat/7.0.42

Firebug 确认已执行 POST:

POST http://localhost:8080/withme/register | 405 Method Not Allowed | localhost:8080

我已禁用应用程序中的所有过滤器。

我想知道 curl 和浏览器 POST 请求有什么区别?为什么 grails 以不同的方式处理它?最后,如何解决它..

Grails 2.2.4 Groovy 版本:2.1.6 JVM:1.7.0_21 供应商:Oracle Corporation 操作系统:Mac OS X

更新

我发现请求正文很重要。使用没有正文的 curl 发送请求成功,但设置正文会导致请求失败。好一个:

$ curl http://localhost:8080/withme/register -X POST -v -L
* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 8080 (#0)
> POST /withme/register HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Transfer-Encoding: chunked
< Date: Thu, 08 Aug 2013 09:39:22 GMT
< 
* Connection #0 to host localhost left intact
ok* Closing connection #0

还有一个不好的:

$ curl http://localhost:8080/withme/register -X POST -v -L -d "email=&password=&passwordConfirmation=&firstName=&lastName=&country=&city=&_action_Register=Register"
* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 8080 (#0)
> POST /withme/register HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5
> Host: localhost:8080
> Accept: */*
> Content-Length: 100
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 100 out of 100 bytes
< HTTP/1.1 405 Method Not Allowed
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Content-Length: 977
< Date: Thu, 08 Aug 2013 09:40:31 GMT
< 
* Connection #0 to host localhost left intact
<html><head><title>Apache Tomcat/7.0.42 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 405 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The specified HTTP method is not allowed for the requested resource.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.42</h3></body></html>* Closing connection #0

还有什么区别?

【问题讨论】:

    标签: grails url-routing grails-2.0 http-status-code-405


    【解决方案1】:

    我已经解决了奇怪的问题。

    Grails 将&lt;g:actionSubmit value="Register" /&gt; 呈现为

    <input type="submit" value="Register" name="_action_Register">
    

    注意这个奇怪的名字。 Grails 从value 属性推导出它,并在选择要调用的操作时使用它。在我的情况下它会导致问题,因为 POST /register 应该由 save 操作处理。

    改成&lt;input type="submit" value="Register"&gt;即可解决问题。

    【讨论】:

    • 很有趣,但如果您有一个正确操作的表单,请使用g:submitButton。如您所见,g:actionSubmit 将创建这个神奇的名称并将您的表单提交给另一个操作(当您需要提交操作时使用!= 表单操作)。
    • 我不会把它称为一个奇怪的问题 - 这就是它的工作原理per documentation
    猜你喜欢
    • 2013-11-14
    • 2014-07-16
    • 2018-02-02
    • 2018-05-28
    • 2011-01-13
    • 1970-01-01
    • 2017-12-19
    • 2016-12-12
    • 2023-03-12
    相关资源
    最近更新 更多