无法使用 redux-saga 从服务器产生 json 响应

Posted

技术标签:

【中文标题】无法使用 redux-saga 从服务器产生 json 响应【英文标题】:Can't yield json response from server with redux-saga 【发布时间】:2018-05-10 00:10:42 【问题描述】:

我正在尝试使用堆栈 react redux 和 redux-saga 并了解所需的最少管道。

我做了一个 github repo 来重现我得到的错误:

    https://github.com/kasra0/react-redux-saga-test.git 运行应用程序:npm run app 网址:http://localhost:3000/

该应用由一个简单的组合框和一个按钮组成。 从组合中选择一个值后,单击按钮会调度一个操作,该操作仅包含获取一些 json 数据。 服务器收到正确的请求(基于选定的值),但在 let json = yield call([res, 'json']) 这一行。我得到了错误:

我从浏览器得到的错误信息:

 index.js:2177 uncaught at equipments at equipments 
   at takeEvery 
   at _callee 
 SyntaxError: Unexpected end of input
 at runCallEffect (http://localhost:3000/static/js/bundle.js:59337:19)
 at runEffect (http://localhost:3000/static/js/bundle.js:59259:648)
 at next (http://localhost:3000/static/js/bundle.js:59139:9)
 at currCb (http://localhost:3000/static/js/bundle.js:59212:7)
 at <anonymous>

它来自我的一个传奇:

import call,takeEvery,apply,take  from 'redux-saga/effects'
import action_types                 from '../redux/actions/action_types'

let process_equipments = function* (...args)
    let department = args[0] 
    let fetch_url = `http://localhost:3001/equipments/$department`
    console.log('fetch url : ',fetch_url)
    let res  =  yield call(fetch,fetch_url, mode: 'no-cors')
    let json =  yield call([res, 'json']) 
    // -> this is the line where something wrong happens


export function* equipments() 
    yield takeEvery(action_types.EQUIPMENTS,process_equipments)

我在管道中做错了,但我找不到哪里。

非常感谢您的帮助!

卡斯拉

【问题讨论】:

很可能与响应结果不是 JSON 格式有关。试试yield call([res, 'text']),看看实际效果如何。 (或查看您的网络标签) 嗨,谢谢你的线索。我检查了网络以查看响应的内容类型,并且确实收到了 application/json 。我刚刚使用了 then yield call([res, 'text']) 并且它没有错误地通过,但是即使我有响应,console.log(json) 也是空的 【参考方案1】:

redux-saga 的角度来看,所有代码都略微正确-call 效果按顺序执行了两个承诺。

let res  =  yield call(fetch,fetch_url, mode: 'no-cors')
let json =  yield call([res, 'json']) 

但是在no-cors模式下使用fetch意味着程序代码将无法获得响应正文,因为请求模式是opaque,这样:https://fetch.spec.whatwg.org/#http-fetch

如果您想从不同的来源获取信息,请使用带有适当 HTTP 标头的 cors 模式,例如 Access-Control-Allow-Origin,更多信息请参见此处:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

【讨论】:

谢谢!!这就是我的问题的解决方案;-)。我刚刚添加了 res.setHeader('Access-Control-Allow-Origin','localhost:3000');在服务器上,它通过了。 ....当然还有你所说的客户端:让 res = yield call(fetch,fetch_url, mode:'cors')【参考方案2】:

不使用call 方法来调用.json() 的另一种方式。

let res  =  yield call(fetch,fetch_url, mode: 'no-cors')

// instead of const json =  yield call([res, res.json]);
let json =  yield res.json();

console.log(json)

【讨论】:

以上是关于无法使用 redux-saga 从服务器产生 json 响应的主要内容,如果未能解决你的问题,请参考以下文章

使用 redux-saga 作为中间件,在 root saga 文件中使用的 All 效果和 Fork 效果都比较有用

Redux:从组件请求成功或错误流(使用 redux-saga)

从 redux-saga 函数访问 React 上下文值

为啥使用 Redux-Observable 而不是 Redux-Saga?

P17:Redux-saga 的安装和配置

酶集成测试:axios.get 调用未在 redux-saga 中执行