3

在涉及到宁静的东西、ajax 等等时,总共 n00b,所以请保持温和。

我有一个问题,我采用了示例 ServiceStack“Todo”服务,并试图开发一个使用该服务作为数据源的移动客户端。我正在尝试了解这一切是如何工作的,这样我就可以构建一个我认为 SS 比 WCF/WebAPI 更适合的特定服务。

无论如何,假设该服务正在运行, http://localhost:1234/api/todos 我已经启用了基于将其他各种帖子中的信息拼凑在一起的 CORS 支持。所以我的配置函数看起来像这样:

Plugins.Add(new CorsFeature());

            this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
            {
                httpRes.AddHeader("Access-Control-Allow-Origin", "*");
                //Handles Request and closes Responses after emitting global HTTP Headers
                if (httpReq.HttpMethod == "OPTIONS")
                {
                    httpRes.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                    httpRes.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
                    httpRes.StatusCode = 204;
                    httpRes.End();
                }
            });

我在 TodoService 上有一个这样的服务方法:

[EnableCors]
        public object Post(Todo todo)
        {

            var t = Repository.Store(todo);
            return t;
        }

使用浏览器 (FF/IE) 如果我调用这个 ajax 函数:

var todo = { content: "this is a test" };
            $.ajax(
            {
                type: "POST",
                contentType: "application/json",
                data: JSON.stringify(todo),
                timeout:20000,
                url: "http://localhost:1234/api/todos",
                success: function (e) {
                    alert("added");
                    app.navigate("Todo");
                },
                error: function (x, a, t) {
                    alert("Error");
                    console.log(x);
                    console.log(a);
                    console.log(t);
                }
            }
            );

http://localhost:1234,然后一切正常。待办事项被添加,并且在成功函数中,“e”包含服务创建的返回待办事项对象。但是,如果我从其他任何地方(http://localhost:9999即运行移动客户端应用程序的 asp.net 开发服务器)调用它,那么尽管执行了 Service 方法,并且确实在服务器端添加了 todo,但响应返回给 jquery是空的,它会立即触发错误函数。

我确信我在做一些愚蠢的事情,但我一辈子都看不到它。有人有任何线索吗?提前致谢...

更新:现在看来工作正常,问题似乎是

 httpRes.AddHeader("Access-Control-Allow-Origin", "*");

在“选项”块之外。所以在 apphost 中工作的代码是

Plugins.Add(new CorsFeature());
            this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
            {

                //Handles Request and closes Responses after emitting global HTTP Headers
                if (httpReq.HttpMethod == "OPTIONS")
                {
                    httpRes.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                    httpRes.AddHeader("Access-Control-Allow-Origin", "*");
                    httpRes.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
                    httpRes.StatusCode = 204;
                    httpRes.End();
                }
            });
4

1 回答 1

4

所以原来我的原始代码有问题;修改后的代码是:

Plugins.Add(new CorsFeature());
            this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
            {

                //Handles Request and closes Responses after emitting global HTTP Headers
                if (httpReq.HttpMethod == "OPTIONS")
                {
                    httpRes.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                    //this line used to be outside the if block so was added to every header twice.                      
                    httpRes.AddHeader("Access-Control-Allow-Origin", "*");
                    httpRes.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
                    httpRes.StatusCode = 204;
                    httpRes.End();
                }
            });

因此,CorsFeature() 插件似乎可以正确处理 POST、GET 的所有 CORs 内容,并且 RequestFilter 正在处理飞行前 OPTIONS 请求(混淆 - 为什么插件不只处理 OPTIONS 请求?);在旧代码中,每个请求(通过插件和过滤器)都添加了两次 allow-origin 标头,这似乎使 jquery 或浏览器感到困惑。

并不是说我完全理解其中的任何内容,我还有一些阅读要做:) 无论如何,这一切都变得毫无意义,因为我使用的移动框架(DXTreme)似乎无法处理 JSONP 以外的任何东西(因为对我没有好处)我需要 POST/PUT)作为跨域的 Rest Data 源,所以我已经不得不走代理路线,或者转储框架,或者找到解决我的问题的其他方法。

于 2013-02-24T13:12:00.303 回答