javascript - Django 表单 JSON
问题描述
请告诉我问题出在哪里:我需要处理一个 JSON 请求,我应该访问什么,我应该返回什么?这就是问题的本质,因为我在服务器上得到了答案,令牌有问题。
联系人.html:
<form class="feedback__form" id="contact_form" role="form" action="{% url 'contact' %}" method="post">
{% csrf_token %}
<div class="feedback__inv-msg feedback__response-msg">
<span> ERROR</span>
</div>
<div class="feedback__form-wrapper">
<ul class="feedback__field-list">
<li class="feedback__field-item">
<div class="feedback__field-title txt txt_font_mp_regular txt_size_18"><span>YOUR NAME</span></div>
<div class="feedback__field-inp">
{{ contact_form.contact_name }}
</div>
</li>
<li class="feedback__field-item">
<div class="feedback__field-title txt txt_font_mp_regular txt_size_18"><span>YOUR MAIL</span></div>
<div class="feedback__field-inp">
{{ contact_form.contact_email }}
</div>
<li class="feedback__field-item">
<div class="feedback__field-title txt txt_font_mp_regular txt_size_18"><span>YOUR PHONE</span></div>
<div class="feedback__field-inp">
{{ contact_form.contact_phone }}
</div>
<li class="feedback__field-item">
<div class="feedback__field-title txt txt_font_mp_regular txt_size_18"><span>YOUR PROBLEM</span></div>
<div class="feedback__field-inp">
{{ contact_form.content }}
</div>
</li>
<div class="feedback__controls">
<button class="btn btn_compact feedback__sender" type="submit">SEND</button>
</div>
<div class="feedback__response">
<div class="feedback__positive feedback__response-msg"><span>YOUR MESSAGE WAS SENT</span></div>
<div class="feedback__negative feedback__response-msg"><span>YOUR MESSAGE WASNT SENT</span></div>
</div>
</form>
<script type="text/javascript">
class Form {
constructor(){
this.element = document.querySelector(`.feedback`)
this.init()
this.isValid = false
this.values = {}
}
addClassesToImps(){
for(let elem of this.element.querySelectorAll(`input`))
elem.classList.add(`inp`)
this.element.querySelector(`input[type="hidden"]`).classList.remove(`inp`)
}
getStructure(){
this.addClassesToImps()
this.form = this.element.querySelector(`.feedback__form`)
this.inps = this.element.querySelectorAll(`.inp`)
this.reqInps = this.element.querySelectorAll(`.inp[required]`)
this.sender = this.element.querySelector(`.feedback__sender`)
}
handleValidityCheck(elem){
if(!elem.checkValidity()){
elem.classList.add(`inp_invalid`)
this.isValid = false
} else {
elem.classList.remove(`inp_invalid`)
elem.classList.add(`inp_valid`)
}
}
handleSenderClick(e){
e.preventDefault()
this.isValid = true
for(let elem of this.reqInps){
this.handleValidityCheck(elem)
}
if(this.isValid){
this.element.classList.remove(`feedback_inv`)
this.values.name = this.element.querySelector(`.inp[name="contact_name"]`).value
this.values.mail = this.element.querySelector(`.inp[name="contact_email"]`).value
this.values.phone = this.element.querySelector(`.inp[name="contact_phone"]`).value
this.values.text = this.element.querySelector(`.inp[name="content"]`).value
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData(``, this.values)
.then(data => {
console.log(data); // JSON data parsed by `response.json()` call
});
} else {
this.element.classList.add(`feedback_inv`)
return false
}
}
init(){
this.getStructure()
console.log(this)
this.sender.addEventListener(`click`, this.handleSenderClick.bind(this))
for(let elem of this.inps){
elem.addEventListener(`focusout`, this.handleValidityCheck.bind(this, elem))
}
}
}
let feedback = new Form()
</script>
表格.py:
class ContactForm(forms.Form):
contact_name = forms.CharField(required=True)
contact_email = forms.EmailField(required=True)
contact_phone = forms.CharField(required=False)
content = forms.CharField(
required=True,
widget=forms.Textarea(attrs={'id': 'my_field', 'class': 'feedback__textarea inp'})
)
# the new bit we're adding
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = "Name:"
self.fields['contact_email'].label = "Mail:"
self.fields['contact_phone'].label = "Phone"
self.fields['content'].label = "Your problem"
视图.py:
def contact(request):
form_class = ContactForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
contact_name = request.POST.get(
'contact_name'
, '')
contact_phone = request.POST.get(
'contact_phone'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
form_content = request.POST.get('content', '')
# Email the profile with the
# contact information
template = get_template('contact_template.txt')
context = {
'contact_name': contact_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
'form_content': form_content,
}
content = template.render(context)
email = EmailMessage(
"New message from form",
content,
'', ['mail@mail.com'],
headers = {'Reply-To': contact_email }
)
email.send()
return HttpResponse('')
在 urls.py 中:
...
path('contact/', views.contact, name='contact'),
...
在服务器控制台中:
Forbidden (CSRF token missing or incorrect.)
"POST / HTTP/1.1" 403
在浏览器控制台中:
SyntaxError: JSON.parse: unexpected character at line 2 column 1 of the JSON data
请不要推荐使用 jQuery 的选项,它在这个项目中被排除在外
解决方案
在您的脚本中,使用以下行获取 csrf 令牌值
var token = jQuery("[name=csrfmiddlewaretoken]").val();
当您向服务器发送数据时,请使用另外一个参数
headers: {'X-CSRFToken': token}
它将解决您的 csrf 错误并确保您在表单中定义了 {% csrf_token %}。
推荐阅读
- google-analytics - 是否有谷歌分析的类型
- c - eBPF BPF_ARRAY 查找
- r - 通过根据条目和变量值之间传递的时间量创建唯一 ID 列来对数据框行进行分组
- prometheus - Prometheus 算术运算符:缺少匹配项的默认值?
- python - 三元运算符不使用条件赋值
- python - 是否可以从 python 代码对象中获取 AST?
- python - Python:如何生成 1.0 和 0.0 的随机矩阵,但使用浮点数?
- office365 - 请选择一个证书来验证您自己
- javascript - 如何根据按钮选择隐藏和显示单个表格?
- javascript - Gatsby 博客文章 - 如何将丰富的片段添加到从 YouTube 嵌入的视频中