使用 Falcor 发送设置和呼叫请求
Sending set and call requests with Falcor
我一直在尝试使用 Falcor 模型从端口 3000 上的 react-client 向 node.js 服务器发送设置和呼叫请求,该服务器在端口 3001 上为路由器提供服务。get-request 在没有一个问题,但设置和调用请求我只是收到内部服务器错误。
我尝试将正文解析器添加到服务器并将 crossDomain:true
添加到客户端请求,因为它解决了一些问题,但似乎这些不是原因。
然后我尝试将 set-request 分离到它自己的路由,但结果还是一样。
老实说,目前我什至不确定是 falcor、客户端或后端的问题。更令人困惑的是 get-request 工作得很好。
我注意到有关设置和呼叫请求的一些事情。当向服务器发送该类型的请求时,请求的查询对象为空。当向同一路由发送工作获取请求时,对象是这样的
{ paths: '[["user","marisanity",["_id","games_length"]]]',
method: 'get' }
不知道有没有帮助。
这是服务器端:
server.js
const express = require('express');
const config = require('config');
const app = express();
const FalcorServer = require('falcor-express');
const bodyParser = require('body-parser');
const userRouter = require('./src/routes/users');
if (!config.get('jwtPrivateKey')) {
console.error('jwtPrivateKey is not defined, shutting down');
process.exit(1);
}
app.use(bodyParser.urlencoded({extended: false}));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", `http://localhost:3000`);
res.header("Access-Control-Allow-Headers", "Authorization, X-Auth-Token, Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
app.use('/api/users/model.json', FalcorServer.dataSourceRoute((req) => userRouter(req)));
const port = process.env.PORT || 3001;
app.listen(port, () => {console.log(`Listening on port ${port}`)});
users.js
const userRepository = require('./../db/repositories/userRepository');
const Router = require('falcor-router');
let UserRouterBase = Router.createClass([
{
route: "user[{keys:username}][{keys:fields}]",
get: async function (pathSet) {
const results = [];
return await userRepository.findByUsername(pathSet.username).then(user => {
if (user === null || user.games.length === 0) {
return ({
path: ['users'],
value: "No results"
});
} else {
pathSet.fields.forEach(field => {
if (field === 'games_length') {
results.push({
path: ['user', pathSet.username[0], "games_length"],
value: user.games.length
});
} else {
results.push({
path: ['user', pathSet.username[0], field],
value: String(user[field])
});
}
});
return results;
}
})
},
async set(jsonGraphArg) {
console.log(jsonGraphArg);
return {
path: ['user', 'marisanity', 'games_length'],
value: 'test'
};
}
}
]);
let UserRouter = function (res) {
UserRouterBase.call(this);
//used later to pass token for this component
this.res = res;
};
UserRouter.prototype = Object.create(UserRouterBase.prototype);
module.exports = function (res) {
return new UserRouter(res);
};
这是客户端:
import React, {Component} from 'react';
import Falcor from 'falcor';
import HttpDataSource from 'falcor-http-datasource';
export default class Test extends Component {
constructor(props) {
super(props);
this.userModel = this.constructUserModel();
}
componentDidMount() {
//works just fine
this.fetchUserInfo();
//this produces error
this.editUSerInfo();
}
constructUserModel = () => {
return new Falcor.Model({
source: new HttpDataSource('http://localhost:3001/api/users/model.json', {
crossDomain: true,
headers: {
'x-auth-token': "secret"
}
})
});
};
editUSerInfo = () => {
this.userModel.setValue(["user", "marisanity","games_length"], 3).then(function(done){
console.log(done);
});
};
fetchUserInfo = () => {
this.userModel.get(["user", ['marisanity'], ['_id', 'games_length']])
.then(function (response) {
console.log(response);
});
};
}
最后这是浏览器中显示的错误:
OPTIONS http://localhost:3001/api/users/model.json 500 (Internal Server Error)
requestObserver @ request.js:135
o.subscribe @ request.js:30
sendSetRequest @ sendSetRequest.js:41
set @ RequestQueueV2.js:40
setRequestCycle @ setRequestCycle.js:63
_subscribe @ SetResponse.js:89
subscribe @ ModelResponse.js:90
(anonymous) @ setValue.js:25
subscribe @ ModelResponse.js:90
(anonymous) @ ModelResponse.js:137
then @ ModelResponse.js:134
Test._this.editUSerInfo @ Wow.js:55
componentDidMount @ Wow.js:18
commitLifeCycles @ react-dom.development.js:18071
commitAllLifeCycles @ react-dom.development.js:19630
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
commitRoot @ react-dom.development.js:19854
(anonymous) @ react-dom.development.js:21402
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:21401
performWorkOnRoot @ react-dom.development.js:21324
performWork @ react-dom.development.js:21229
performSyncWork @ react-dom.development.js:21203
requestWork @ react-dom.development.js:21058
scheduleWork @ react-dom.development.js:20871
scheduleRootUpdate @ react-dom.development.js:21566
updateContainerAtExpirationTime @ react-dom.development.js:21592
updateContainer @ react-dom.development.js:21660
push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:21973
(anonymous) @ react-dom.development.js:22125
unbatchedUpdates @ react-dom.development.js:21448
legacyRenderSubtreeIntoContainer @ react-dom.development.js:22121
render @ react-dom.development.js:22196
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ Yay.js:4
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous)
此问题是由无效的 CORS 配置引起的。通过用 Express 的官方 CORS 中间件替换旧配置解决了这个问题:
const cors = require('cors');
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
optionsSuccessStatus: 200
};
app.use(cors(corsOptions));
我一直在尝试使用 Falcor 模型从端口 3000 上的 react-client 向 node.js 服务器发送设置和呼叫请求,该服务器在端口 3001 上为路由器提供服务。get-request 在没有一个问题,但设置和调用请求我只是收到内部服务器错误。
我尝试将正文解析器添加到服务器并将 crossDomain:true
添加到客户端请求,因为它解决了一些问题,但似乎这些不是原因。
然后我尝试将 set-request 分离到它自己的路由,但结果还是一样。
老实说,目前我什至不确定是 falcor、客户端或后端的问题。更令人困惑的是 get-request 工作得很好。
我注意到有关设置和呼叫请求的一些事情。当向服务器发送该类型的请求时,请求的查询对象为空。当向同一路由发送工作获取请求时,对象是这样的
{ paths: '[["user","marisanity",["_id","games_length"]]]',
method: 'get' }
不知道有没有帮助。
这是服务器端:
server.js
const express = require('express');
const config = require('config');
const app = express();
const FalcorServer = require('falcor-express');
const bodyParser = require('body-parser');
const userRouter = require('./src/routes/users');
if (!config.get('jwtPrivateKey')) {
console.error('jwtPrivateKey is not defined, shutting down');
process.exit(1);
}
app.use(bodyParser.urlencoded({extended: false}));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", `http://localhost:3000`);
res.header("Access-Control-Allow-Headers", "Authorization, X-Auth-Token, Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
app.use('/api/users/model.json', FalcorServer.dataSourceRoute((req) => userRouter(req)));
const port = process.env.PORT || 3001;
app.listen(port, () => {console.log(`Listening on port ${port}`)});
users.js
const userRepository = require('./../db/repositories/userRepository');
const Router = require('falcor-router');
let UserRouterBase = Router.createClass([
{
route: "user[{keys:username}][{keys:fields}]",
get: async function (pathSet) {
const results = [];
return await userRepository.findByUsername(pathSet.username).then(user => {
if (user === null || user.games.length === 0) {
return ({
path: ['users'],
value: "No results"
});
} else {
pathSet.fields.forEach(field => {
if (field === 'games_length') {
results.push({
path: ['user', pathSet.username[0], "games_length"],
value: user.games.length
});
} else {
results.push({
path: ['user', pathSet.username[0], field],
value: String(user[field])
});
}
});
return results;
}
})
},
async set(jsonGraphArg) {
console.log(jsonGraphArg);
return {
path: ['user', 'marisanity', 'games_length'],
value: 'test'
};
}
}
]);
let UserRouter = function (res) {
UserRouterBase.call(this);
//used later to pass token for this component
this.res = res;
};
UserRouter.prototype = Object.create(UserRouterBase.prototype);
module.exports = function (res) {
return new UserRouter(res);
};
这是客户端:
import React, {Component} from 'react';
import Falcor from 'falcor';
import HttpDataSource from 'falcor-http-datasource';
export default class Test extends Component {
constructor(props) {
super(props);
this.userModel = this.constructUserModel();
}
componentDidMount() {
//works just fine
this.fetchUserInfo();
//this produces error
this.editUSerInfo();
}
constructUserModel = () => {
return new Falcor.Model({
source: new HttpDataSource('http://localhost:3001/api/users/model.json', {
crossDomain: true,
headers: {
'x-auth-token': "secret"
}
})
});
};
editUSerInfo = () => {
this.userModel.setValue(["user", "marisanity","games_length"], 3).then(function(done){
console.log(done);
});
};
fetchUserInfo = () => {
this.userModel.get(["user", ['marisanity'], ['_id', 'games_length']])
.then(function (response) {
console.log(response);
});
};
}
最后这是浏览器中显示的错误:
OPTIONS http://localhost:3001/api/users/model.json 500 (Internal Server Error)
requestObserver @ request.js:135
o.subscribe @ request.js:30
sendSetRequest @ sendSetRequest.js:41
set @ RequestQueueV2.js:40
setRequestCycle @ setRequestCycle.js:63
_subscribe @ SetResponse.js:89
subscribe @ ModelResponse.js:90
(anonymous) @ setValue.js:25
subscribe @ ModelResponse.js:90
(anonymous) @ ModelResponse.js:137
then @ ModelResponse.js:134
Test._this.editUSerInfo @ Wow.js:55
componentDidMount @ Wow.js:18
commitLifeCycles @ react-dom.development.js:18071
commitAllLifeCycles @ react-dom.development.js:19630
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
commitRoot @ react-dom.development.js:19854
(anonymous) @ react-dom.development.js:21402
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:21401
performWorkOnRoot @ react-dom.development.js:21324
performWork @ react-dom.development.js:21229
performSyncWork @ react-dom.development.js:21203
requestWork @ react-dom.development.js:21058
scheduleWork @ react-dom.development.js:20871
scheduleRootUpdate @ react-dom.development.js:21566
updateContainerAtExpirationTime @ react-dom.development.js:21592
updateContainer @ react-dom.development.js:21660
push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:21973
(anonymous) @ react-dom.development.js:22125
unbatchedUpdates @ react-dom.development.js:21448
legacyRenderSubtreeIntoContainer @ react-dom.development.js:22121
render @ react-dom.development.js:22196
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ Yay.js:4
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous)
此问题是由无效的 CORS 配置引起的。通过用 Express 的官方 CORS 中间件替换旧配置解决了这个问题:
const cors = require('cors');
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
optionsSuccessStatus: 200
};
app.use(cors(corsOptions));