Research on Axios cookie problem and form upload problem

Source: Internet
Author: User
Tags chrome developer

Since entering the Vue, has been using Axios this library to do some asynchronous requests. Recently encountered a little problem in Cross-domain, cookie and form upload, do a simple research and summary. This article will cover the solution of using Axios to successfully get the contents of a response message in a cross-domain situation and to have the cookie successfully set up, and a small problem when uploading form data using Axios. one, the same domain cookie problem

First of all, look at a case of the same domain cookie example clear the entire process in order to face cross-domain situation can be better elaborated. Service-side code as follows, access to the/get-cookie interface, through the session casually set the field time, so that the response message with the Set-cookie field, in the browser section set cookies, the content of this cookie is the corresponding sessionId. Then access/test-cookie can determine whether the browser side of the cookie is set to succeed, if the setting is successful, then the message sent by the browser will automatically bring the cookie field, the server can also be based on the cookie to find the corresponding session. If the setting fails, the message sent by the browser does not bring the cookie field, and the server cannot find the corresponding session, thus returning the error.

Const EXPRESS = require (' Express ')
const PATH = require (' path ')
const COOKIEPARSER = require (' Cookie-parser ') C2/>const session = require (' express-session ')
const FILESTORE = require (' Session-file-store ') [session]

Let App = Express ()

app.use ('/static ', Express.static (Path.join (__dirname, './static '))
App.use (Cookieparser ( )
App.use (session ({
  store:new filestore (),
  secret: ' Hongchh ',
  resave:false,
  Saveuninitialized:false
})

app.use ('/get-cookie ', (req, res) => {
  req.session.time = Date.now ()
  Res.json ({result: ' OK '})
}

App.use ('/test-cookie ', (req, res) => {
  if (req.session.time) {
    console.log (' session.time: ' + Req.session.time)
    Console.log (req.cookies)
    Res.json ({result: ' OK '})
  } else {
    Res.json ({result : ' Error '}}
})

App.listen (8000)

console.log (' http://localhost:8000/static/index.html ')

The front end code is as follows, the front end has only two buttons, the triggering click event can call two interfaces respectively.

window.onload = function () {' Usr strict ' document.getElementById (' Get-cookie '). Addeventlis Tener (' Click ', GetCookie, False) document.getElementById (' Test-cookie '). AddEventListener (' Click ', TestCookie, False var getresult = document.getElementById (' Get-result ') var testresult = document.getElementById (' Test-result ') Fu Nction GetCookie () {axios.get ('/get-cookie '). Then (function (res) {if (Res.status = =) {GetResult. Textcontent = Res.data.result} else {getresult.textcontent = ' ERROR '}}} function Testco Okie () {axios.get ('/test-cookie '). Then (function (res) {if (Res.status = =) {Testresult.textconten t = Res.data.result} else {testresult.textcontent = ' ERROR '}})} 

First click on the Get-cookie button, and then click the Test-cookie button, send message information as follows, you can see, get-cookie response message has set-cookie fields, and Test-cookie request message automatically with the cookie field 。 The Chrome Developer tool also lets you see the cookie-set success. The server also outputs the session and cookie information for the response.

cross-domain cookie problem

To implement Cross-domain, split the server into 2 servers, 1 provide static resources, and 1 provide interfaces. The server that accesses port 8002 loads the front-end interface, and then the server that accesses port 8001 across domains invokes the Get-cookie and Test-cookie interfaces. In order to satisfy the cross-domain, there should be a access-control-allow-origin field in the response message for the 8001 server, and the field value set to ' * ' indicates access to all other domains.

const Express = require (' Express ') const COOKIEPARSER = require (' Cookie-parser ') const session = Require (' express-session ') const FILESTORE = require (' Session-file-store ') (session) Let App = Express () app.use (cookie 

Parser ()) App.use (session ({Store:new filestore (), Secret: ' Hongchh ', Resave:false, saveuninitialized:false}) App.use ('/get-cookie ', (req, res) => {req.session.time = Date.now () res.header (' Access-control-allow-origin ', ' *  ') Res.json ({result: ' OK '})} app.use ('/test-cookie ', (req, res) => {res.header (' access-control-allow-origin '), ' * ') if (req.session.time) {console.log (' session.time: ' + req.session.time) console.log (req.cookies) Res. JSON ({result: ' OK '})}/else {Res.json ({result: ' Error '}}}) App.listen (8001) console.log (' Http://localhos T:8001/') 
Const EXPRESS = require (' Express ')
const PATH = require (' path ') let

app = Express ()

app.use ('/static '), Express.static (Path.join (__dirname, './static '))
App.listen (8002)

console.log (' http://localhost:8002/') )

The front end only needs minor modifications to change the URL of the calling interface to an absolute address. The following is the Get-cookie, Test-cookie is similar.

function GetCookie () {
  axios.get (' Http://localhost:8001/get-cookie '). Then (function (res) {
    if (res.status = = = =] {
      getresult.textcontent = Res.data.result
    } else {
      getresult.textcontent = ' ERROR '
    }
  }} c12/>}

Similarly, first Get-cookie, then Test-cookie, the results are as follows. There was no error in the access, but the cookie was not successfully set. You can see that there are set-cookie fields in the Get-cookie response message, but the Test-cookie request message does not carry a cookie field. You can also see that cookies are not set up successfully through the Chrome developer tool.

After viewing the Axios document, you find that you need to configure the Withcredentials property, and the Withcredentials property of the global configuration Axios is true.

Axios.defaults.withCredentials = True

After the configuration is complete, the test is done and the results are as follows. A Cookie,test-cookie request message that is successfully set up will automatically bring cookies. But in addition to the successful setting of cookies, the front end also complains, and cannot read the contents of the main part of the response message.

According to the error message, it should be said that the value of the Access-control-allow-origin field cannot be set to ' * ' directly. Therefore, we directly modify its value to determine the domain name to try. Make the following modifications to Get-cookie and Test-cookie.

App.use ('/get-cookie ', (req, res) => {
  req.session.time = Date.now () res.header (
  ' Access-control-allow-origin ', ' http://localhost:8002 ')
  Res.json ({result: ' OK '})
})

App.use ('/ Test-cookie ', (req, res) => {
  res.header (' Access-control-allow-origin ', ' http://localhost:8002 ')
  if ( Req.session.time) {
    console.log (' session.time: ' + req.session.time)
    console.log (req.cookies)
    Res.json ({result: ' OK '})
  } else {
    Res.json ({result: ' ERROR '}}
  }
})

Continue the test, the results are similar to the previous, successfully set the cookie, but can not get the content of the main part of the response message, and continue the error. Other content similar here does not repeat screenshots. Only the information for this error is different, as shown in the following figure. It looks as if the change to the domain name is a successful solution to the previous problem, and then the new problem needs to be addressed.

According to the error tip, we also need to set the Access-control-allow-credentials value to true in addition to the Access-control-allow-origin field. Follow the prompts to modify the server-side code as shown below.

App.use ('/get-cookie ', (req, res) => {
  req.session.time = Date.now () res.header (
  ' Access-control-allow-origin ', ' http://localhost:8002 ')
  res.header (' access-control-allow-credentials ', ' true ') )
  Res.json ({result: ' OK '})
}

app.use ('/test-cookie ', (req, res) => {
  Res.header (' Access-control-allow-origin ', ' http://localhost:8002 ')
  res.header (' access-control-allow-credentials ', ' true ') )
  if (req.session.time) {
    console.log (' session.time: ' + req.session.time)
    Console.log (req.cookies)
    Res.json ({result: ' OK '})
  } else {
    Res.json ({result: ' ERROR '}}
  }
})

Continue with the test and get the results as follows. This time, in addition to setting cookies correctly, you can read the contents of the main part of the response message without any errors.

As a result, you can conclude that using Axios in a cross-domain situation requires that you first configure the Axios Withcredentials property to be true. Then the server also needs to configure the response message header Access-control-allow-origin and access-control-allow-credentials two fields, Access-control-allow-origin The value of the field needs to be a defined domain name and cannot be replaced directly with ' * ', and the value of the access-control-allow-credentials needs to be set to true. Both the front-end and service-side are well configured for Cross-domain access and to carry cookie information. third, the form uploads the question

In the process of uploading form data using Axios, I usually do this as follows.

var formData = {
  key1: ' value1 ',
  key2: ' value2 ',
  key3: ' Value3 '
}
axios.post ('/upload ', formData) . Then (function (res) {
  if (res.status = =/do
    something
  }
})

The above practice in the Nodejs Express service side using Body-parser can be correctly resolved to the request message inside the body part of the data, that is, I submitted the form data, so played for a long time did not appear any problems. The pit was not started until recently in a course assignment with 1 Python flask backstage classmates. Data submitted in the same way as above, cannot be extracted from the form data in his background program. His backstage access to the form data by Req.form, with the Express req.body seems to be a little different. So I guess the body-parser middleware of Express has extracted the data of the main part of the message, and his req.form only extracts the standard form data. You can also verify the conjecture by modifying the data in the Axios post. Code changes are as follows, using the FormData provided by JS to wrap the form data that needs to be submitted. Finally, the server successfully received the front-end uploaded data.

var formData = new FormData ()
formdata.append (' Key1 ', ' value1 ')
formdata.append (' Key2 ', '
value2 ') Formdata.append (' Key3 ', ' value3 ')
axios.post ('/upload ', formData). Then (function (res) {
  if (res.status = = () {
    //do Something
  }
})

This is probably a simple understanding of the difference between the first way is to post a JS object, will be turned into a JSON string in the form of submission. The second is to submit a FormData object, the standard form data object. Therefore, if you encounter similar problems in Java, PHP, and other backgrounds, you can also consider trying to resolve them with a FormData object.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.