Django POST请求Ajax无法在服务器端获取数据
我正在尝试在我的网站上获取订阅表单。我用的是条纹。我可以使用他们的API将数据发送到Stripe。但是,从Stripe接收数据后,我无法将其保存在服务器端:Django POST请求Ajax无法在服务器端获取数据,django,ajax,Django,Ajax,我正在尝试在我的网站上获取订阅表单。我用的是条纹。我可以使用他们的API将数据发送到Stripe。但是,从Stripe接收数据后,我无法将其保存在服务器端: // In subscription.js: $( function() { var customerEmail = document.querySelector("[data-email]").getAttribute('data-email'); var submissionURL
// In subscription.js:
$( function() {
var customerEmail = document.querySelector("[data-email]").getAttribute('data-email');
var submissionURL = document.querySelector("[data-redirect]").getAttribute('data-redirect');
var stripeSubscriptionForm = document.getElementById('subscriptionId');
var cardElement = elements.create("card", { style: style });
// Mounting the card element in the template
cardElement.mount("#card-element");
stripeSubscriptionForm.addEventListener('submit', function(event){
event.preventDefault(); // Before submitting, we need to send the data to our database too
theForm = event.target; // getting the form; same as using getElementById, but using the event only
theFormData = new FormData(theForm);
stripe.createPaymentMethod( { type : 'card', // this is what's sent to stripe
card : cardElement,
billing_details : { email : customerEmail, }
},
)
.then( (result) => { // Once stripe returns the result
// Building the data
theFormData.append('card', cardElement);
theFormData.append('billing_details', customerEmail);
theFormData.append('payement_method', result.paymentMethod.id);
// Setting up the request
const xhr = new XMLHttpRequest() // Creating an XHR request object
xhr.open(method, url); // Creating a GET request
// Setting up the header
xhr.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest"); // Ajax header
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); // Ajax header
xhr.setRequestHeader("X-CSRF-TOKEN", "{{ csrf_token }}"); // csrf_token
xhr.onload = function() { // After server sends response data back
console.log('Got something back from server ')
const response = xhr.response; // 1) get the response object of the XHR request object
if (xhr.status === 201 ){ // If the item is created
const responseJson = JSON.parse(response)
console.log('and json response: ', responseJson);
}
else{
console.log('httpRequest status: ', httpRequest.status); // Let's see what's going on
}
}
// Sending the form data
xhr.send(theFormData); // Sending the xhr request
});
});
然后,在my views.py中:
def post(self, request, *args, **kwargs):
''' Receives the subscription form '''
subscriber_form = SubscriberForm(request.POST)
billing_address_form = CompanyAddressForm(request.POST)
subscription_form = SubscriptionForm(request.POST)
if subscriber_form.is_valid() and billing_address_form.is_valid() and subscription_form.is_valid():
print ('forms are valid')
billing_address = billing_address_form.save()
subscriber_instance = subscriber_form.save(commit = False)
subscriber_instance.address = billing_address
print ('######################################################')
if request.META.get('CONTENT_TYPE', '').lower() == 'application/json' and len(request.body) > 0:
print ('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
try:
body_data = json.loads(request.body)
print (body_data)
except Exception as e:
request_body = request.body
print (request_body)print ('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
else:
print ("request.META.get('CONTENT_TYPE', ''): ", request.META.get('CONTENT_TYPE', '') )
## Creating a customer in stripe: Need the data from the front-end:
customer_stripe = stripe.Customer.create( payment_method = data.get('payment_method', None),
email = data.get('email', None),
invoice_settings = { 'default_payment_method': data.get('payment_method', None), },
)
## Creating a subscription in stripe
subscription = stripe.Subscription.create( customer = customer_stripe.id, items = [{'plan': plan_idx, }], # plan_idx is the plan id from stripe
expand = ['latest_invoice.payment_intent'] )
form = SubscriptionForm(request.POST)
if form.is_valid():
subscription_instance = form.save()
else:
context['form'] = SubscriptionForm(request.POST)
return render(request, self.template_name, context)
## Creating the same customer for ourselves
user = request.user
...
customer, created = Customer.objects.get_or_create(...)
return render(request, reverse('dashboard') )
else:
... # Re-render the forms with errors
return render(request, self.template_name, context)
问题是我得到了:
######################################################
request.META.get('CONTENT_TYPE', ''): multipart/form-data; boundary=----WebKitFormBoundaryIeaE9GpJ2EXQBkZK
如何访问我的数据?我的表单都没有图像或文件,但是,即使我的表单是多部分/表单数据(将来可能需要将其添加到订阅服务器),我如何使用body\u data=json.loads(request.body)
获取数据
编辑1:
因此,我想既然我已经访问了request对象以在post方法中获取表单,那么可能我应该首先准备好request.body,因为Django抱怨说,一旦您触摸了request对象,您就无法再次读取流。因此,以下是修改:
def post(self, request, *args, **kwargs):
''' Receives the subscription form '''
request_body = request.body
try:
body_data = json.loads(request_body)
except Exception as e:
print ('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
print (request_body)
print ('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
但这又回来了
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
request_body: b'------WebKitFormBoundaryBBzJCNQS96b76EKx\r\nContent-Disposition: form-data; name="csrfmiddlewaretoken"\r\n\r\n0ryuWTIxVRPjDGe0c9Fxj7Sc3KeCmBtAkiFK5EAlriY0QtAmwo6ip\r\n------WebKitFormBoundaryBBzJCNQS96b76EKx\r\nContent-Disposition: form-data; name="name"\r\n\r\nABC\r\n------WebKitFormBoundaryBBzJCNQS96b76EKx\r\nContent-Disposition: form-data; name="email"\r\n\r\nemail@gmail.com\r\n...'
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
问题是为什么会出现例外情况,这个WebKitFormBoundary业务是什么
编辑2
因此,当我在服务器端打印POST请求时,我确实获得了数据:
def post(self, request, *args, **kwargs):
''' Receives the subscription form '''
# request_body = request.body
print ('request_post: ', request.POST)
print ('')
在我的控制台中返回以下内容:
request_post: <QueryDict: {'csrfmiddlewaretoken': ['OOPVcfGU2WfcPl3ld-Jx1L7XI1vSHfFhp0v1SIzQHpIyWrrhrH0d03HYnS7DdssZ'], 'name': ['ABC'], 'email': ['email@gmail.com'],...
那么,这是否告诉我们数据正在进入服务器端,并且检索数据时出现问题?我认为您的问题在于您在javascript代码中发布的数据, 您向服务器发送的不是json对象,而是表单对象
theFormData=newformdata(theForm)代码>
如果您想发布一个json对象,您应该首先创建一个javascript对象,然后在其上使用json.stringyfy
方法创建一个json并将该json发送到您的服务器
比如说
sendData={field1:“value1”,field2:“value2”}
send(JSON.stringify(sendData));
为什么您要使用GET
方法发送数据,并尝试在您的视图中获取数据的body
?您怎么说我使用了GET?我确实看过了,我正在使用POST-requestit,这是在您的javascript代码中这样写的xhr.open(方法,url);//创建GET请求
。当你想访问已经发布给你的数据时,你可以通过variable=request.POST[“name\u of_data\u field”]
或者更好的版本variable=request.POST.get(“name\u of_data\u field”,None)
而不是request.body
@Mahyar来访问,你说的对,我应该在Django视图中使用.POST。我发现为什么我应该使用.POST而不是.body。通常,您会使用.body来处理JSON,正如下面的回答https://stackoverflow.com/a/37570142/3549766
如果您能详细说明为什么在这种情况下应该使用.POST方法,那么我建议您创建一个答案,并将其标记为正确答案。这是因为本例中的原因可以帮助其他人处理Ajax、JSON和formData。
request_body: b'------WebKitFormBoundaryG87zmkiNu0fTWY0g\r\nContent-Disposition: form-data; name="csrfmiddlewaretoken"\r\n\r\nOOPVcfGU2WfcPl3ld-Jx1L7XI1vSHfFhp0v1SIzQHpIyWrrhrH0d03HYnS7DdssZ\r\n------WebKitFormBoundaryG87zmkiNu0fTWY0g\r\nContent-Disposition: form-data; name="name"\r\n\r\nABC\r\n------WebKitFormBoundaryG87zmkiNu0fTWY0g\r\nContent-Disposition: form-data; name="email"\r\n\r\nemail@gmail.com\r\n------WebKitFormBoundaryG87zmkiNu0fTWY0g\r\n...'