link1781 link1782 link1783 link1784 link1785 link1786 link1787 link1788 link1789 link1790 link1791 link1792 link1793 link1794 link1795 link1796 link1797 link1798 link1799 link1800 link1801 link1802 link1803 link1804 link1805 link1806 link1807 link1808 link1809 link1810 link1811 link1812 link1813 link1814 link1815 link1816 link1817 link1818 link1819 link1820 link1821 link1822 link1823 link1824 link1825 link1826 link1827 link1828 link1829 link1830 link1831 link1832 link1833 link1834 link1835 link1836 link1837 link1838 link1839 link1840 link1841 link1842 link1843 link1844 link1845 link1846 link1847 link1848 link1849 link1850 link1851 link1852 link1853 link1854 link1855 link1856 link1857 link1858 link1859 link1860 link1861 link1862 link1863 link1864 link1865 link1866 link1867 link1868 link1869 link1870 link1871 link1872 link1873 link1874 link1875 link1876 link1877 link1878 link1879 link1880 link1881 link1882 link1883 link1884 link1885 link1886 link1887 link1888 link1889 link1890 link1891 link1892 link1893 link1894 link1895 link1896 link1897 link1898 link1899 link1900 link1901 link1902 link1903 link1904 link1905 link1906 link1907 link1908 link1909 link1910 link1911 link1912 link1913 link1914 link1915 link1916 link1917

[Vue.js] Axios request receiving a CORS error only when inside a callback/async function

I’m using VueJS for an app when building. The server there is is written in Golang and has been set to accept CORS. In the app, in one of my components, searchBar, there is set it to fetch some data before it is created.

var searchBar = {
prop: […],
data: function() {
return { … };
},
beforeCreate: function() {
var searchBar = this;

axios.request({
url: ‘/graphql’,
method: ‘post’,
data: {
‘query’: ‘{courses{id, name}’
}
})
.then(function(response) {
searchBar.courses = response.data.data.courses;
});
},
methods: { … },
template: `…`
};

Axios works perfectly here. It gets the data I need. searchBar has a button which causes it to emit an event which is then picked up by another component, searchResults. Upon receiving the event, searchResults will fetch some data.

var searchResults = {
data: function() {
return { … }
},
mounted: function() {
var sr = this;

this.$bus.$on(‘poll-server’, function(payload) {
var requestData = {
url: ‘/graphql’,
method: ‘post’,
data: { … },

};

axios.request(requestData)
.then(function(response) {
console.log(response);
}
);
});
},
template: `…`
};

Note that my Axios request call is now inside a callback function. When this call is performed, I receive a CORS error:

Access to XMLHttpRequest at ‘http://127.0.0.1:9000/graphql' from origin ‘http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

My server is located at http://127.0.0.1:9000, with the client in http://127.0.0.1:8080. Here is the content of the OPTIONS request of the second request call.

For comparison, here is the request header of the first request call (that works!).

there is already set my Golang server to support CORS via go-chi/cors. This is how set it up.

router := chi.NewRouter()

// Enable CORS.
cors := cors.New(cors.Options{
AllowedOrigins: []string{“*“},
AllowedMethods: []string{“POST”, “OPTIONS”},
AllowedHeaders: []string{“Accept”, “Authorization”, “Content-Type”, “X-CSRF-Token”},
ExposedHeaders: []string{“Link”},
AllowCredentials: true,
MaxAge: 300,
})

router.Use(
render.SetContentType(render.ContentTypeJSON),
middleware.Logger,
middleware.DefaultCompress,
middleware.StripSlashes,
middleware.Recoverer,
cors.Handler,
)

router.Post(“/graphql”, gqlServer.GraphQL())

return router, db

What is causing the error when having and how can it be solved?

Solution :

This CORS error is expected. The CORS plugin you are using does request filtering for you. If you look at the list of allowed headers, you can see it’s missing the header called snb-user-gps-location that you are trying to send in the axios call.

Either add that header to the allowed list, or don’t send it from the front end.

Solution 2:

I still suspect the go-chi CORS setup. I would suggest looking at setting up CORS by hand. It’s not that difficult. This page will get a basic setup: https://flaviocopes.com/golang-enable-cors/

If that works with the nested API setup, we can then work backwards to determine the go-chi config issue.

Update:

I would also investigate the other middleware steps - commenting out all non-essential ones.

Middleware handlers normally inspect the r *http.Request or write headers to the w http.ResponseWriter and then the final handler will write to the response body. But throughout the middleware chain the following header/body write flow should look like one of these two flows:

Success:

w.Header().Set(…) // headers
w.Write(…) // body

Note the above flow will issue an implicit http status code write, to keep headers appearing first and body second:

w.Header().Set(…) // headers
w.WriteHeader(http.StatusOK) // implicit success http status code
w.Write(…) // body

Failure:

In the event of reporting a runtime error, the flow should be:

w.Header().Set(…) // headers
w.WriteHeader(http.StatusInternalServerError) // some unrecoverable error
w.Write(…) // optional body

The reason I bring this up, I’ve seen 3 types of bugs which mess up this flow:

bad middleware handlers write headers after the body causing client confusion
calling http.Error thinking that stops the API dead - instead of returning immediately after the http.Error and ensuring no subsequent middleware handlers are called
write the same header twice. Rewriting headers in a subsequent handler will cause the client to see the last version (thus clobbering any previous versions)

So to fully trace things, I would log.Println all header/body writes for the API to ensure the above flow is correct and no intended values are being overwritten.

Solution 3:

What you are missing is Access-Control-Allow-Origin. This is a response header telling the browser that cors is allowed for this domain. Check if there is a problem with the cors configuration. A configuration problem perhaps? Maybe you need to allow it for 120.0.0.1:8080.