I am trying to GET data with my client vueJS on port 8080 from the REST API on port 3000. This is resulting in a CORSE Error. A POST is working fine. To fix this I tried to create a proxy as described here https://medium.com/js-dojo/how-to-deal-with-cors-error-on-vue-cli-3-d78c024ce8d3.
//vue.config.js
module.exports={
devServer:{
proxy: {
'/teams': {
target: 'http://192.168.70.54:3000',
ws: true,
changeOrigin: true,
secure: false
}}}}
I want to redirect my traffic to the 3000 port.
//rest.js
function getTeams() {
var returnVal;
axios({
method: 'get',
url: REST_API + '/teams',
responseType: 'json'
})
.then(function (response) {
console.log(response.data); //Is what I want to return
returnVal = response.data;
});
console.log(returnVal); //Is undefined
return returnVal.data;
}
I am printing response.data to the console but my returnVal is always undefined. What am I missing?
This is my network log in the browser.
General:
Request URL: http://localhost:8080/teams
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8080
Response Headers:
Referrer Policy: no-referrer-when-downgrade
access-control-allow-header: Origin, X-Request-With, Content-Type, Accept
access-control-allow-methods: GET, POST
access-control-allow-origin: *
connection: close
content-length: 1070
content-type: application/json
Date: Tue, 17 Dec 2019 18:57:14 GMT
Request Headers:
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: localhost:8080
Referer: http://localhost:8080/setup
User-Agent: Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Raspbian Chromium/74.0.3729.157 Chrome/74.0.3729.157 Safari/537.36
There's a lot going on in this question.
Firstly, let's focus on this bit:
function getTeams() {
var returnVal;
axios({
method: 'get',
url: REST_API + '/teams',
responseType: 'json'
})
.then(function (response) {
console.log(response.data); //Is what I want to return
returnVal = response.data;
});
console.log(returnVal); //Is undefined
return returnVal.data;
}
The first log line is logging the correct value but the second log line is undefined.
This is to be expected. It has nothing to do with CORS or proxying.
The problem is that the axios request is asynchronous, so the then callback won't be called until some point in the future. By that point the function will have returned. You should find that the log lines are being logged in the 'wrong' order for the same reason.
You can't return an asynchronously retrieved value synchronously from a function. Using async/await may make it look like you can but even that is a fudge, hiding the underlying promises.
You have two options:
Return a promise from getTeams. That kicks the problem of waiting up to the calling code.
If you are inside a component you can set a data property inside the then callback. This is instead of returning a value.
Then we have the other parts of your question.
It would seem that you have successfully managed to configure a proxy. Difficult to be sure but from everything you've included in the question that seems to be working correctly. You wouldn't be getting the correct data in your console logging if the proxy wasn't working.
However, there are a lot of CORS headers in your response. If you're using a proxy then you don't need the CORS headers. A proxy is an alternative to CORS, you don't use both.
As for why your CORS request was failing prior to using a proxy, it's difficult to say from the information provided in the question.
Related
I'm using a Asp.net Core 2.2 Web API and ReactJS Axios, but sometimes (about 1 in 100 times) the response status is 200 but the data is an empty string.
The server side Controller code is:
[Route("api/[controller]")]
[ApiController]
public class SomeApiController : ControllerBase
{
[HttpPost("GetData")]
public IActionResult GetData([FromBody] int id_search)
{
// *Here I get a list data from back using the id_search*
string json = JsonConvert.SerializeObject(List_data, Formatting.Indented));
// *Here I write the json string in a text file, for debbug the data to send*
return Ok(json);
}
}
So far everything is fine, the json string i wrote in the text file have the data like this:
[
{
"cod_db": 1,
"nom_db": "Nom1"
},
{
"cod_db": 2,
"nom_db": "Nom2"
}
]
The Axios client javascript code is (I'm using axios 0.19.2):
import axios from 'axios';
const clienteAxios = axios.create({
baseURL: 'https://localhost:44364/api/'
}):
export default clienteAxios;
The client side axios method is:
const getData = () => {
const config = {
headers: {
'Content-Type': 'application/json',
// * The next headers I wrote because i think the problem could be CORS too, but I dont know if are necessary *
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true ,
'Cache-Control': 'no-cache',
'Access-Control-Allow-Headers': 'Content-type, Accept'
}
}
var id_search = 1;
clienteAxios.post('SomeApi/GetData', id_search, config)
.then(d=>{
console.log(d);
})
.catch(d=>{
console.log("error");
console.log(d);
})
}
And most of the time the response have data, but sometimes (it is difficult to happen), the response data is an empty string, even though the server side effectively sent data (I know because the text file records the data to send) and the .then method was execute with code status 200.
I don't know why this is happening, but I suspect that it could be because of CORS. I have this cors configurations in the Startup.cs archive:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//CORS Activación
services.AddCors(
options => options.AddPolicy("EnableCORS",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build();
})
);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//Enable CORS policy "AllowCors"
app.UseCors("EnableCORS");
app.UseHttpsRedirection();
app.UseMvc();
}
Is there something I am doing wrong, or does anyone know why this is happening?
Edit: After a lot of attempts, I finally managed to recreate the error (remember that it is difficult to happen). The Chrome browser developer tools
Console tab shows nothing and the Network tab shows:
Headers:
General:
Request URL: https://localhost:44364/api/Login/GetDataBases
Request Method: POST
Status Code: 200
Remote Address: [::1]:44364
Referrer Policy: no-referrer-when-downgrade
Response Headers:
access-control-allow-credentials: true
access-control-allow-origin: *
content-length: 0
content-type: text/plain; charset=utf-8
date: Fri, 04 Sep 2020 10:16:46 GMT
server: Microsoft-IIS/10.0
status: 200
vary: Origin
x-powered-by: ASP.NET
Request Headers:
:authority: localhost:44364
:method: POST
:path: /api/Login/GetDataBases
:scheme: https
accept: application/json, text/plain, */ *
accept-encoding: gzip, deflate, br
accept-language: es-ES,es;q=0.9
access-control-allow-credentials: true
access-control-allow-headers: Content-type, Accept
access-control-allow-origin: *
cache-control: no-cache
content-length: 1
content-type: application/json
origin: http://localhost:3000
referer: http://localhost:3000/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Request Payload:
1
No properties
Response:
This request has no response data available.
I suspect that it could be because of CORS.
As you mentioned, the most of requests that ReactJS client send can get expected data, in my view, the issue would not be caused by CORS.
But configuring with both AllowAnyOrigin and AllowCredentials methods is insecure and not recommended, you can specify the allowed origins using WithOrigins method.
sometimes (about 1 in 100 times) the response status is 200 but the data is an empty string.
Based on your code, it seems that you host the app on local, to troubleshoot the issue, you can set break point inside your action method, then debug and trace the id_search and List_data.
Besides, if you host your app on server, to troubleshoot the issue, you can try to write application logs then check application logs to find useful info.
private readonly ILogger _logger;
public SomeApiController(ILogger<SomeApiController> logger)
{
_logger = logger;
}
[HttpPost("GetData")]
public IActionResult GetData([FromBody] int id_search)
{
_logger.LogInformation($"Client passed id_search is '{id_search}'");
//var List_data = YourService.GetDataById(id_search);
if (List_data.Count() < 1)
{
_logger.LogInformation($"Can not get data based on id_search '{id_search}'");
}
string json = JsonConvert.SerializeObject(List_data, Formatting.Indented);
_logger.LogInformation($"Get data based on id_search: {json}");
return Ok(json);
}
I'm using zapworks studio to develop an AR experience. It uses Z.ajax to make the ajax calls. I make a GET request and a POST request. I'm also using smileupps to host couchdb(they have free hosting). Here's the CORS configuration:
credentials: false; headers:Accept, Authorization, Content-Type, Origin;
methods: GET,POST,PUT,DELETE,OPTIONS,HEAD; origins: *
Everything works fine when launching ZapWorks Studio on windows. When scanning the zapcode with an android device, however, the post ajax call fails. Only the post. I am using basic authentication. I enforce that only the admin can manage the database on couchdb. I can access the host from both the desktop and the phone from a web browser to do everything manually.
I tried everything I could of to solve the problem: remove authentication, change the CORS configuration...nothing works. I thought it was an issue with CORS but everything works fine on windows and on the mobile just the POST fails...I keep getting a status code of 0.
EDIT - New info, testing on apitester also works on the desktop and mobile.
EDIT - Here's the zpp to show the logic
EDIT - Tried with REST Api Client on my phone and it worked as well. This can only be a CORS issue or something with zapworks. Weird that it works on windows but not on the phone.
EDIT - I found out what the problem is, but not how to fix it. So I set a proxy to debug the requests made from zapworks studio following this tutorial. It seems that it does a preflight request but gets the response
"HTTP/1.1 405 Method Not Allowed"
even though the payload is
{"error":"method_not_allowed","reason":"Only DELETE,GET,HEAD,POST
allowed"}.
Here's the request:
OPTIONS /ranking HTTP/1.1
Host: somehost.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: null
User-Agent: Mozilla/5.0 (Linux; Android 8.0.0; SM-G950U1 Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/67.0.3396.87 Mobile Safari/537.36
Access-Control-Request-Headers: authorization,content-type,x-requested-with
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US
X-Requested-With: com.zappar.Zappar
and the response:
HTTP/1.1 405 Method Not Allowed
Server: CouchDB/1.6.0 (Erlang OTP/R15B01)
Date: Mon, 18 Jun 2018 21:22:12 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 76
Cache-Control: must-revalidate
Allow: DELETE,GET,HEAD,POST
Access-Control-Expose-Headers: Cache-Control, Content-Type, Server
Access-Control-Allow-Origin: null
Connection: keep-alive
{"error":"method_not_allowed","reason":"Only DELETE,GET,HEAD,POST allowed"}
which clearly shows that POST is allowed...
On the windows side, there doesn't seem to be a preflight request for some reason and my guess is that's why it works. Now the question is how do I configure CORS on couchdb to work on android. These are the configurations available:
enable_cors: true
credentials: false
headers:Accept, Authorization, Content-Type, Origin
methods:GET,POST,PUT,DELETE,OPTIONS,HEAD
origins:*
This is the code:
const Open_SansRegular_ttf0 = symbol.nodes.Open_SansRegular_ttf0;
parent.on("ready", () => {
const Plane0 = symbol.nodes.Plane0;
let ajaxParameters : Z.Ajax.Parameters = {
url: "https://something.smileupps.com/test/_all_docs?include_docs=true",
headers: {"Authorization": "Basic my64encoding"},
method: "GET",
timeout: 3000
};
// Perform the AJAX request
Z.ajax(ajaxParameters, (statusCode, data, request) => {checkRequest(statusCode, data);});
ajaxParameters = {
url: "https://something.smileupps.com/test",
headers: {"Content-Type":"application/json", "Authorization": "Basic my64encoding"},
method: "POST",
body: '{"name" : "asdasd", "something": 234}',
timeout: 3000
};
Z.ajax(ajaxParameters, (statusCode, data, request) => {checkRequest(statusCode, data);});
});
function checkRequest(statusCode, data) {
if (statusCode === 0) {
Open_SansRegular_ttf0.text("Unable to connect - check network connection.");
console.log("Unable to connect - check network connection.");
return;
}
if (statusCode < 200 || statusCode >= 300) {
Open_SansRegular_ttf0.text("HTTP request failed: " + statusCode);
console.log("HTTP request failed: " + statusCode);
return;
}
// Attempt to parse the data returned from the AJAX request as JSON
let parsedData;
try {
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
parsedData = JSON.parse(data);
} catch (e) {
Open_SansRegular_ttf0.text("Unable to parse JSON: " + e);
console.log("Unable to parse JSON: " + e);
return;
}
return parsedData;
}
EDIT
Here's the request on windows
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US
Authorization:Basic mybase64encoding
Connection:keep-alive
Content-Length:37
Content-Type:application/json
Host:http://something.smileupps.com/test
Origin:file://
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ZapWorksStudio/4.0.4-stable Chrome/58.0.3029.110 Electron/1.7.9 Safari/537.36
X-DevTools-Request-Id:3680.9
X-Requested-With:XMLHttpRequest
and the response:
Access-Control-Allow-Origin:file://
Access-Control-Expose-Headers:Cache-Control, Content-Type, ETag, Server
Cache-Control:must-revalidate
Content-Length:95
Content-Type:text/plain; charset=utf-8
Date:Mon, 18 Jun 2018 21:36:22 GMT
ETag:"1-512f89feb3d0a88781119e772ec6fd7b"
Location:http://something.smileupps.com/test
Server:CouchDB/1.6.0 (Erlang OTP/R15B01)
No preflight.
Your problem is in the request: Origin: null is usually what you get when the Web page containing the xhr request is opened with the file: rather than the http or https protocol. You won't get any successful CORS request with such an origin.
I am running a local Springboot server, that when I access it locally in the browser, gives me a valid JSON object properly formatted (I verified this via JSON formatter).
I am also locally running a React application using node. I am attempting to use fetch() to get back that JSON object and running into issues. Finally got around CORs header issues, but not cannot figure out why the JSON object isn't coming back. Here's my code
var headers = new Headers();
headers.append("Content-type", "application/json;charset=UTF-8");
var myInit = { method: 'GET',
headers: headers,
mode: 'no-cors',
cache: 'default',
};
fetch(`http://localhost:3010/getJSON`, myInit)
.then(function(response){
console.log(response.data);
console.log(response);
console.log(JSON.parse(JSON.stringify(response)));
},function(error){
console.log(error);
});
So when I run this in Chrome with the debugger, the responses to the 3 log statements are:
1st logger
undefined
2nd logger
Response {type: "opaque", url: "", redirected: false, status: 0, ok: false,
…}
body
:
(...)
bodyUsed
:
false
headers
:
Headers {}
ok
:
false
redirected
:
false
status
:
0
statusText
:
""
type
:
"opaque"
url
:
""
__proto__
:
Response
3rd logger
{}
I have tried many different JSON parsing, stringify, etc, to no avail.
The next confusing part, is if within the Chrome debugger I go to the "Network" tab, click on the /getJSON, it shows me the entire JSON object just fine in both the "Preview" and "Response" tabs. So clearly Chrome is connecting to it correctly. Here's Chrome's "Headers" tab within "Network":
Request URL:http://localhost:3010/getJSON
Request Method:GET
Status Code:200
Remote Address:[::1]:3010
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Content-Type:application/json;charset=UTF-8
Date:Thu, 12 Oct 2017 16:05:05 GMT
Transfer-Encoding:chunked
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:3010
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
I have tried to mimic this header in my request, but not sure how it differs? Any help would be greatly appreciated as I am currently banging my head against the way with this!
You're getting an opaque response, which tells me that maybe you haven't completely resolved the cors headers situation. If you're fetching from the client, I would suggest proxying that through your nodejs so that instead of calling your springboot service, you call node, thus getting rid of the cors issues.
EDIT
You could create something like this:
import express from 'express';
import request from 'request';
const router = express.Router();
router.get('/proxyname', (req, res) => {
// Removing IPv4-mapped IPv6 address format, if present
const requestUrl = [your service's endpoint];
request(requestUrl, (err, apiResponse, body) => {
res.status(apiResponse.statusCode);
try {
res.json(JSON.parse(body));
} catch (e) {
res.send(body);
}
});
});
export default router;
and then on your nodejs server file, add it, like this:
import proxy from '[path to proxy file above]';
app.use('/path-to-endpoint', proxy);
and then call that from the client instead of your SpringBoot service.
I'm trying to issue a CORS get request in Vue via axios. Everything works well so far, but if I need to authenticate via basic auth, I cannot get it to work.
Heres my code
getData: function() {
let vm = this; // assign vue instance to vm
axios.get('url', {
withCredentials: true,
auth: {
username: 'name',
password: 'pass'
}
}).then(function(response) {
console.log(response)
}).catch(function(error) {
console.log(error)
})
}
Even though I entered the credentials, as well as the url correctly, I always get a 401 response. It looks like this.
HTTP/1.1 401 Authorization Required
Date: Wed, 01 Feb 2017 16:23:31 GMT
WWW-Authenticate: Basic realm="'Realm'"
Content-Length: 499
Keep-Alive: timeout=15
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
The raw request looks like that
OPTIONS 'url' HTTP/1.1
Host: 'host'
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://localhost:9000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76
Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
DNT: 1
Referer: http://localhost:9000/pages/blog_cc/blog_cc.html
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: de,en;q=0.8
What am I missing? With Postman and the exact same credentials, everything works like a charm. Even in Chrome directly.
I saw that this question was already asked a few times, but all the posed answers on other threads are no solution for me. I cannot issue the request from node, for example.
Edit: I also tried issuing a request with vanilla JS, also to no avail. It seems the problem lies in the backend. Here's my code, nevertheless.
let xml = new XMLHttpRequest();
xml.open('GET', api, true);
xml.setRequestHeader('Authorization', 'Basic: ' + btoa(user + ':' + pass));
xml.send();
I had the same experience and my workaround was using the following set up to deal with communicating with an OAuth server we had set up:
axios({
headers: { "Content-Type": "application/x-www-form-urlencoded" },
method: "post",
url: REVOKE_URL,
auth: {
username: CLIENT_ID,
password: CLIENT_SECRET
},
data: {
datastuff: actualData
}
});
This worked after futile attempts at using axios.post for days.
Axios version: 0.18.0
So I was looking for example of how to do a post for this and couldn't find a good one. Got it working and it looks like:
const { MAILCHIMP_KEY } = process.env;
const url = "https://us{yourRegionNumber}.api.mailchimp.com/3.0/lists/{yourlistid}/members/";
const client = axios.create({
auth: {
username: "yourmailchimpusername", //This could be your email
password: MAILCHIMP_KEY
},
headers: {
"Content-Type": "application/json"
}
});
const mailChimpRes = await client.post(url, {
email_address: `${email}`,
status: "subscribed",
merge_fields: {
FNAME: `${firstName}`,
LNAME: `${lastName}`
}
});
You could try passing the withCredentials: true, option to the Axios request, if it's a cross site request.
According to their docs, mailchimp does not support client-side requests, so you have to route it through server-side :/
First off, I just wanted to say that I have read through all of the other threads relating to this topic, but haven't had any luck. Here's a breakdown of the issue:
Goals
Retrieve a CSRF token from Sails when the Ember Application starts
Inject that CSRF token into every AJAX request that is initiated from the Ember Application
To satisfy goal 1, I created an Ember Initializer that runs when the application first boots up (if there is a better place for this, I'm totally open to suggestions). To satisfy goal 2, I retrieve the CSRF token from Sails and then attempt to use Ember.$.ajaxSetup() to ensure the CSRF token is passed either as a header (X-CSRF-Token) or parameter (_csrf). I also ensure that I'm using the withCredentials option to ensure the cookie is set. Here's the code:
// initializers/csrf.js
import Ember from 'ember';
import config from '../config/environment';
export function initialize() {
Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) {
Ember.$.ajaxSetup({
data: {
'_csrf': result._csrf
},
xhrFields: { withCredentials: true }
});
}, function(error) {
console.log(error);
});
}
export default {
name: 'csrf',
initialize: initialize
};
All of this appears to work as I can see in Chrome dev tools that the CSRF token is being retrieved and when I make an AJAX request, I see the data appended to the POST data or added as a header (tried both options). Here's the code I'm running and all of the associated headers:
Ember.$.post(config.APP.API_URL + '/auth/register', {
'email': _this.get('email'),
'password': _this.get('password')
}).then(function(response) {
console.log('It worked!');
});
Request Headers
POST /auth/register HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Content-Length: 82
Accept: */*
Origin: http://localhost:4200
CSP: active
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
DNT: 1
Referer: http://localhost:4200/signup
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: sails.sid=s%3AbrABhErTY3-ytTWOKFJ2KBj7DCAzaLDc.apD60Sd%2BW85GSbTfJ7E3B2PrUwnhOsW6GlNpZTu9jFg
Form Data
_csrf:yP7GDiU2-YGmLBfBvQtMPT3-hRpnfK0x-AfA
email:test#test.com
password:q1w2e3r4
Response Headers
HTTP/1.1 403 Forbidden
Vary: X-HTTP-Method-Override
Access-Control-Allow-Origin: http://localhost:4200
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8
Content-Length: 13
Date: Thu, 09 Jul 2015 08:11:34 GMT
Connection: keep-alive
As you can see from the Response headers, I end up receiving a 403 Forbidden - CSRF Mismatch from Sails. Now, here's where it gets a little weird: first, I'm able to run this just fine with Postman. I retrieve a token and then post that token along with the data to the /auth/register url and it works as expected.
I'm also tried removing the initializer and running the following code:
Ember.$.ajaxSetup({
xhrFields: { withCredentials: true }
});
Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) {
Ember.$.post(config.APP.API_URL + '/auth/register', {
'email': _this.get('email'),
'password': _this.get('password'),
'_csrf': result._csrf
}).then(function(response) {
console.log('It worked!');
});
});
This works. However, at this point, I'm at somewhat of a loss as to what the issue actually is. Appreciate any help I can get.
Thanks in advance!
James
#jdixon04, Can you try URL-encoding the CSRF token before sending it through POST? The token mismatch will occur if the token is getting altered from the original.
I found this issue in Github: https://github.com/balderdashy/sails/issues/2266.
I hope this will solve your issue. Do try it and let me know if it works. Thanks.
#jdixon04, got here from your post on my github issue. Actually, isn't the CSRF token going to change at each request made to the server? Then you approach to fix the token when the frontend load cannot cope with this, you may have to fetch the token before each request and use ajaxPrefilter to pass it to the request.
Is that actually related to ember-data-sails? It seems to me you're doing pure ajax here! If you look in my config, you'll realise that pure ajax calls (for authentication as well) are exempted from csrf as I could not make it work as I wished :\ .
Add the x-csrf-token header like this:
Ember.$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': result._csrf
},
xhrFields: { withCredentials: true }
});