ServiceStack (9.54), POST request with JQuery AJAX.
cross domain request, prompts an Error "Request not found".
the service is self-hosted as windows service. FireWall is off.
I have done, what I read, in ServiceStack for cross domain calls (CORS), but without result.
In the web page, the code (which works successfully on localhost) is the following.
jQuery.support.cors = true;
CallTest()
{
$.ajax({
type: 'POST',
url: 'http://dev.testhost.com:18162/TestAPI',
data: JSON.stringify(myRequest),
contentType: 'application/json',
dataType: 'json',
success: function (response, status) {alert(status); },
error : error: function (xhr, err) { alert(err); }
}
}
//in server the code is
//1. at appHost
SetConfig(new ServiceStack.WebHost.Endpoints.EndpointHostConfig
{
GlobalResponseHeaders =
{ //Signal advanced web browsers what HTTP Methods you accept
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type" },
}
}
//2. request
[Route("/TestAPI", "POST")]
[Route("/TestAPI", "GET")]
public class myRequest
{
public string name { get; set; }
public address[] addresses { get; set; }
}
public class myResponse
{
public bool success { get; set; }
public string message { get; set; }
}
// 3. Service
[AddHeader(ContentType = ContentType.Json)]
public myResponse Post(myRequest request)
{
return new myResponse();
}
I debugged with different settings in AppHost code, based on @mythz previous answers, ServiceStack CORS Feature
but it did not work for me.
Update 1: It works for Chrome, not for IE, FIREFOX, OPERA
CHROME Request
POST /TestAPI/CreateReservation HTTP/1.1
Connection: keep-alive
Content-Length: 622
Accept: application/json, text/javascript, */*; q=0.01
Chrome/27.0.1453.116 Safari/537.36
Content-Type: application/json
CHROME RESPONSE
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/3.954 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
IE10 Request
OPTIONS /TestAPI/CreateReservation HTTP/1.1
Accept: */*
Origin: localhost:28014
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type, accept
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Host:
Content-Length: 0
DNT: 1
Connection: Keep-Alive
Pragma: no-cache
IE10 Response
HTTP/1.1 404 Not Found
Content-Length: 3
Content-Type: text/plain
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/3.954 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Update 2: Problem solved, it works, perfect for all browsers tested (Chrome,IE10, Firefox,Opera 12).
Thank you @mythz, @Jon
and @sroes from the stackoverflow question ServiceStack returns 405 on OPTIONS request
step 1. using code from @sroes answer, I replaced in AppHost.Configure the GlobalResponseHeaders,
Plugins.Add(new CorsFeature());
RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
httpRes.AddHeader("Access-Control-Allow-Origin", "*");
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.End();
}
});
step 2: based on @mythz proposal for a route and a method that accepts Options requests. I added in Routes, without actually to create any function for Options.
Routes
.Add<ReservationRequest>("/TestAPI/CreateReservation", "POST, GET, OPTIONS");
Problem solved, it works for me, ServiceStack rocks !!
thanks a lot.
Update 3 : It works also with the proposed code from @mythz.
At the beginning, the code could not compile, because it could not find the EndServiceStackRequest().
(an extension method in the namespace ServiceStack.WebHost.Endpoints.Extensions).
A reference to System.Web also required. Also the httpReq.Method is httpReq.HttpMethod.
The most important is the declaration in Routes for OPTIONS.
Fortunately, it is not necessary to add an empty method 'Options(RequestDto)`.
using System.Web;
using ServiceStack.WebHost.Endpoints.Extensions;
public override void Configure(Container container)
{
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.EndServiceStackRequest();
});
Routes
.Add<ReservationRequest>("/TestAPI/CreateReservation", "POST, OPTIONS");
}
Also, this question OPTIONS Verb for Routes with custom CORS headers is about the same issue.
See this earlier answer on applying CORS on OPTION HTTP Requests.
You can apply the CORS headers to all OPTION requests with a global filter like: