我试图从React / Redux / Django webapp中删除jQuery,并用Fetch API替换$.ajax
方法。我或多或少得到了所有我的GET请求正常工作,我似乎能够点击我的POST请求,但我似乎无法格式化我的请求,以便实际将我的POST数据输入Django { {1}}对象。每次我点击/ sign_in视图时,request.POST
对象都是空的。我的整个应用程序的后端是使用Django表单构建的(没有Django模板,只有React控制的组件),我真的不想重写我的所有视图来使用request.POST
或request.body
以下是我认为相关的所有代码,如果还有其他更多信息,请与我们联系:
这是我用来构建完整POST数据并附加CSRF令牌的curry函数:
request.data
这是我在React应用中使用的API方法:
const setUpCsrfToken = () => {
const csrftoken = Cookies.get('csrftoken')
return function post (url, options) {
const defaults = {
'method': 'POST',
'credentials': 'include',
'headers': {
'X-CSRFToken': csrftoken,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
const merged = merge(options, defaults)
return fetch(url, merged)
}
}
export const post = setUpCsrfToken()
最初打包在React应用程序中的数据就像具有字符串值的对象一样简单:
export const signIn = data => {
return post('/api/account/sign_in/', data)
}
我已经看过这些问题并发现它们名义上有帮助,但是我无法想出为自己综合一个答案,考虑到我认为是Django的一些错综复杂的问题:
谢谢!
答案 0 :(得分:3)
您必须设置相应的X-Requested-With: XMLHttpRequest
标头。 jQuery执行此操作under the hood。
const setUpCsrfToken = () => {
const csrftoken = Cookies.get('csrftoken')
return function post (url, options) {
const defaults = {
'method': 'POST',
'credentials': 'include',
'headers': new Headers({
'X-CSRFToken': csrftoken,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest'
})
}
const merged = merge(options, defaults)
return fetch(url, merged)
}
}
因此,在您的示例中,您需要以下内容:
import React from 'react';
import {
Media,
Dropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
} from 'reactstrap';
import PropTypes from 'prop-types';
const UserPreview = ({user}) => (
this.toggle = this.toggle.bind(this);
this.state = {
DropdownOpen: false
};
}
toggle() {
this.setState({
DropdownOpen: !this.state.DropdownOpen
});
}
<tr className="user">
<td>
<Media>
<img
alt={`${user.name} avatar`}
className="avatar d-flex mr-3"
src={user.url} />
<Media body>{user.name}</Media>
</Media>
</td>
<td>
<Dropdown isOpen={this.state.DropdownOpen} toggle={this.toggle}>
<DropdownToggle caret>
Admin
</DropdownToggle>
<DropdownMenu>
<DropdownItem>Read</DropdownItem>
<DropdownItem>Write</DropdownItem>
</DropdownMenu>
</Dropdown>
</td>
</tr>
);
UserPreview.propTypes = {
user: PropTypes.shape({
name: PropTypes.string,
// TODO: add an url proptype.
url: PropTypes.string,
}).isRequired,
};
export default UserPreview;