How to resolve CORS issue on my ExtJS store - api

I am required to use Ext.Store not Ext.Ajax as my requirement. Here is my code:
Ext.define('Vidly.store.Customers', {
extend: 'Ext.data.Store',
alias: 'store.customers',
storeId: 'customers',
model: 'Vidly.model.Customer',
autoLoad: true,
proxy: {
type: 'ajax',
headers : {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, DELETE, PUT',
'Access-Control-Allow-Headers': 'x-requested-with, Content-Type, origin, authorization, accept, client-security-token'
},
api : {
read : 'https://localhost:44378/api/Customers'
},
reader: {
type: 'json',
}
}
});
I keep getting this error: XMLHttpRequest at 'https://localhost:44378/api/Customers?_dc=1612003742512&page=1&start=0&limit=25' from origin 'http://localhost:1967' 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.
I am not sure if I should adjust something on my API or on my SPA but I already removed all CORS related code plus it works on my other SPA.
EDIT
Here is my .NET 5 API Startup under ConfigureServices method
services.AddCors();
and under Configure method
app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());

I was able to resolve the issue by changing my Ext Store call for some reason it is sending default headers that the API rejects. The video guides in the internet uses my previous syntax, luckily I found a better syntax that overrides the default headers.
Here is the code
Ext.define('Vidly.store.Customers', {
extend: 'Ext.data.Store',
alias: 'store.customers',
storeId: 'customers',
model: 'Vidly.model.Customer',
autoLoad: true,
proxy: {
type: 'rest',
url: 'https://localhost:44313/api/Customers',
useDefaultXhrHeader: false,
reader: {
type: 'json',
headers: { 'Accept': 'application/json' },
}
}
});
Using type as rest not ajax. Hope this helps others. Thanks.

Related

Is there any solution to solve CORS error in Vite js? [duplicate]

This question already has answers here:
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
(11 answers)
Closed 9 months ago.
I tried all the solutions which were provided by developers for the same issue. I updated the Vite.config.js file like that-
//vite.config.js
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'#': resolve(__dirname, 'src'),
},
},
server: {
proxy: {
'/api': {
target: 'http://localhost:3000/',
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/api/, '')
},
cors:false
},
},
define: {
'process.env': {}
}
})
I added header properties in both files-
//Login.vue
const header = {
headers: {
'Authorization': 'Bearer ${accessToken}',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': POST, GET, OPTIONS,
'Access-Control-Allow-Credentials': true,
'Sec-Fetch-Mode': no-cors,
'Sec-Fetch-Site': same-site
},
//App.vue
const header = {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Credentials': true,
'Sec-Fetch-Mode': no-cors,
'Sec-Fetch-Site': cross-site,
},
But, when I inspect the code and see under the network header property-
How can I change these header properties or any other way to solve this CORS problem. I want to solve for the frontend side only. Currently, I am running this application in Chrome by disabling security
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security but I want to run it to all the browsers without disabling security.
Get Error-
Any valuable suggestion will help me a lot. Thanks in advance
First, you do not need the 'Access-Control-...' headers on the client side. So you can remove these. You can only set CORS on the server side, in your case this is the Vite server.
You defined a proxy on in the Vite server, but I think you made a mistake there. The target must be the url of the real api server, for example https://example.com/realApi.
Next, in your Vue app, you need to call the api with the local url of your Vite dev server, usually http://localhost:3000 and use /api as the path. Vite will rewrite the url like:
http://localhost:3000/api/TheApiYouAreCalling --> https://example.com/realApi/TheApiYouAreCalling
See vite docs server.proxy and node-http-proxy docs for options.
Hope this helps.
Edit:
If you need a proxy in production, you can fairly easy build a node.js proxy with http-proxy. The code below is an example, where your proxy is located at /proxy on your server. The downside may be that you need to run node.js on your server. The example below is using http, for https see http-proxy docs.
var http = require("http");
var httpProxy = require("http-proxy");
var proxy = httpProxy.createProxyServer({});
const server = http.createServer(function (req, res) {
if (/^\/proxy\/api/.test(req.url)) {
req.url = req.url.replace(/^\/proxy\/api/, "");
proxy.web(req, res, {
target: "https://example.com/realApi",
changeOrigin: true,
secure: false,
});
} else {
res.writeHead(200, { "Content-Type": "text/plain" });
const response = "Proxy running...";
res.end(response);
}
});
server.listen(8080);
You cannot solve CORS on front-end.

Axios: Network Error and not sending request

I am trying to send a get request with auth headers to api from Vue using axios.
When I try to send it, it gives me a Network Error with no info about it. I have also check network tab and the request is not sending at all.
Before I checked the url using postman and https://www.hurl.it/ and it worked as expected.
Also, I have sent a request to this api using axios to get a token.
Thank you.
const token = "token";
let options = {
method: 'GET',
url: 'http://smev.test-it-studio.ru/api/analytics/PortfolioStructure',
headers: {
'Authorization': `Bearer ${token}`
},
};
axios(options).then((data) => {
console.log(data);
}).catch((error) => {
console.log(error.config);
});
EDIT: Here is the error I get:
Error
columnNumber: 15
config: {…}
adapter: function xhrAdapter()
baseURL: "http://smev.test-it-studio.ru"
data: undefined
headers: Object { Accept: "application/json", Authorization: "Bearer token"}
maxContentLength: -1
method: "GET"
timeout: 0
transformRequest: Object [ transformRequest() ]
transformResponse: Object [ transformResponse() ]
url: "http://smev.test-it-studio.ru/api/analytics/PortfolioStructure"
validateStatus: function validateStatus()
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
__proto__: Object { … }
fileName: "http://uralsib-lk.dev/dist/build.js"
lineNumber: 19074
message: "Network Error"
response: undefined
stack: "createError#http://uralsib-lk.dev/dist/build.js:19074:15\nhandleError#http://uralsib-lk.dev/dist/build.js:18962:14\n"
__proto__: Object { … }
build.js:18589:24
With the help from Soleno, I found out that it was AdBlock what was blocking the request.
I had this problem in rails. It was cors as mentioned above.
The rails server won't show logs so it looks like axios isn't sending the request at all.
Thankfully it's an easy fix.
For rails add this to your gemfile:
gem 'rack-cors'
Then add this to config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0,Rack::Cors do
allow do
origins 'localhost:8080'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
Note: Update orgins to the origin of your front end app.

Sencha Touch: Using proxy and POST request and URL generation

I have been trying to do a post request using a proxy. I have tried the direct proxy, rest and ajax proxy, and haven't been able to find a working example for a POST request.
Is it possible? Because all the examples that I have seen seen to be using only GET.
Any working examples, or pointers in this direction?
Also, I couldn't figure what is the correct way to generate URLs for a proxy at run-time, for example, calling a function to return the URL.
It appears that this might not be possible:
http://www.sencha.com/forum/showthread.php?205557-Using-Ext.data.proxy.Ajax-via-a-POST-with-jsonData
If you look at the source code for Ext.data.proxy.Rest you'll see a config object for actionMethods. They're not documented, but you should be able to pass that as a config on your proxy to override it.
For example:
proxy: {
type: 'ajax',
url: 'path/to/foo',
actionMethods: {
create : 'POST',
read : 'POST',
update : 'PUT',
destroy: 'DELETE'
},
reader: {
type: 'json',
rootProperty: 'root',
totalProperty : 'totalCount'
}
}
Easiest example of POST request could be like this:
var obj = new Object();
obj.userId = username;
obj.password = password;
var data = Ext.JSON.encode(obj);
Ext.Ajax.request({
url : 'http://myservice/auth/login?_type=json', // url : this.getUrl(),
method : "POST",
headers: {
'Content-Type': 'application/json'
},
params : data,
useDefaultXhrHeader : false,
withCredentials: true,
success : function(response) {
Ext.Msg.alert("Success", "Welcome "+respObj.user.name);
},
failure : function(response) {
var respObj = Ext.JSON.decode(response.responseText);
Ext.Msg.alert("Error", respObj.status.statusMessage);
}
});
Please note here you can customize url as per your convenience.

passing parameters to RIA service from extjs with json end point

I am trying to communicate with RIA service from extjs using POST for getting response with following code.
var store = Ext.create('Ext.data.Store', {
model: 'RootResults',
proxy: {
type: 'ajax',
actionMethods: 'POST',
url: 'MyService.svc/JSON/GetRes',
headers: {
'Content-type': 'application/json'
},
reader: {
type: 'json',
root: 'GetResResult.RootResults',
totalProperty: 'GetResResult.TotalCount'
}
, pageParam: undefined,
startParam: undefined,
limitParam: undefined
, success: function (response) {
alert(response);
}
}
});
var operation = new Ext.data.Operation({
FId: 1,
SId: 0
});
store.load({ params: Ext.encode(operation) });
i can access it with get.
when i am trying with POST, it returning error - "405 Method Not Allowed".
what to do to make it POST enabled?
When i asked this question, i am bit confused with POST communication between extjs and RIA services.
I solved this with the help of following article
http://www.joseph-connolly.com/blog/post/WCF-RIA-Services-jQuery-and-JSON-endpoint-Part-2.aspx
For accessing WCF RIA Services from jquery or extjs, actually we need to create changeset for CUD(Create-Update-Delete) operations and All of the operations use JSON/SubmitChanges.
I believe that on the server end you need to add HasSideEffects to your method declaration ():
[Invoke(HasSideEffects = true)]
public GetPages(...)
{
}

extjs4 store addes get params in the url

i'm using extjs4 store
In xhtpp calls it shows the http://localhost/home_dir/index.php/questions/content_pie?_dc=1312366604831&hi=&page=1&start=0&limit=25
This is the store code
var content_type_store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: BASE_URL+'questions/content_pie',
method:'POST',
params :{hi:''}
}),
reader: new Ext.data.JsonReader({
root: 'results'
}, [
'qtype',
'qval'
])
});
Even though i set the method as POST its get params appears in url
I'm using codeigniter as my framework. I disabled GET params in CI. Iwnat to send params in post. with ext2 and 3 this code worked fine..
Help me
Thanks
method:'POST' in proxy's config won't work. There is no such config option. However there are two ways to make store use POST. The simplier one - just override getMethod function:
var content_type_store = new Ext.data.Store({
proxy: {
type: 'ajax',
url: BASE_URL+'questions/content_pie',
extraParams :{hi:''},
// Here Magic comes
getMethod: function(request){ return 'POST'; }
},
reader: {
type: 'json',
root: 'results'
}
});
The second way: override proxy's actionMethods property. If you choose this way your proxy should look like this:
// ...
proxy: {
type: 'ajax',
url: BASE_URL+'questions/content_pie',
extraParams :{hi:''},
// Here Magic comes
actionMethods: {
create : 'POST',
read : 'POST',
update : 'POST',
destroy: 'POST'
}
},
// ...