404 not found with api call - Angular to RoR - ruby-on-rails

I am a newbie with Ruby on Rails and I am trying to figure out ways to connect Angular to RoR in a very simple way
Here is my service
mWebApp.service('mWebSrvc', function($http, $log) {
this.getCustomers = function() {
$http({
method : 'GET',
url : 'http://127.0.0.1:3000/api/customers/'
}).success(function(data, status, headers, config) {
$log.log('Done');
angular.forEach(data, function(c) {
$log.log(c.Title);
});
customers = data;
return customers;
});
};
});
When I look under the Net tab in Firebug, I see OPTIONS /api/customers/ 404 Not Found, but if I click on the Response tab within, then I see the JSON file - WTF? And not the JSON tab - again, WTF?
Under Firebug's console -
"NetworkError: 404 Not Found - http://numberForLocalHost:3000/api/customers/"
My Rails server is running in daemon mode - numberForLocalHost:3000 - is this what the issue might be? That it should be calling a true api
If I paste the URL above into any web browser, then I can see the JSON
As usual, thanks in advance

You're getting an OPTIONS request because your browser believes this is a cross origin request.
See this question for example. Is your RoR app also serving your client side angular? If not, you should decide whether it can be (there shouldn't be a reason not to), or you need to reply to the pre-flight OPTIONS request from your server that you are seeing.

I had the very same issue with my Rails + Angular app. I had my cors well set up in my rails app but still nothing, I still got a 404 not found in the angular app. This could be the reason:
Perhaps you have "angular-in-memory-web-api": '0.x.x' in your package.json and also imported in your app.module.ts, as InMemoryWebApiModule and InMemoryDataService. These apparently intercept all calls to an API preventing them from ever reaching your back-end server. When I Removed those dependencies and their declarations, all of a sudden my app started working normally!
Look at this answer for more information.

Related

Shopify API HTTP POST redirecting instead of POSTing

I have code (Classic ASP) which was recently working POSTing orders to Shopify but has now stopped POSTing and either creates an error "A Redirection problem has occurred" or redirects to the admin area of the Shopify site, depending on which XMLHTTP component I employ. The code below still works on older OS but not on Server 2016 where I am working.
I can't find much on Google but there was an indication in the Shopify Forum that the problem was a result of cookies (I have set none) and that this is overcome by sending a header containing X-Shopify-Access-Token:. I tried this using the "Authorize" setRequestHeader but it made no difference, or I got the syntax wrong or something. I used
xmlhttp.setRequestHeader "Authorization","X-Shopify-Access-Token=<token>"
Below is the code that worked a few weeks back. Variable jsondata contains valid JSON to send to create an order.
Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0")
xmlhttp.Open "POST", "https://<api key>:<passowrd>#<sitename>.myshopify.com/admin/orders.json", false, "<api key>", "<password>"
xmlhttp.setRequestHeader "Content-Type", "application/json; charset=utf-8"
xmlhttp.setRequestHeader "Content-Length", Len(jsondata)
xmlhttp.Send jsondata
Set xmlhttp = nothing
I expect a POST and a JSON order response but this is not happening - just a redirection to https://<sitename>.myshopify.com/admin. Any ideas anyone?

Angular Universal / Node: Backend not accessing session. Creating new on each reload

I am using session based authentication in my Angular Universal app. Problem is when http request is made from Angular app, backend (node.js) doesn't access the ongoing session, but creates new. You might think this is because cors, but the thing is, the first initial load only doesn't access session. So when I open up my app on page that has resolver or guard, that is making http request. That http request is going to create new session. Then navigating to other pages in app, it all works. http requests made after initial load will access the session. If I start from page that has no resolver/guards and then navigate to page that has and makes http request, this request will access to session.
Here is how my session is setup in index.js:
var sessionStore = new MySQLStore(options);
app.use(
session({
key: 'sessionStorage',
store: sessionStore,
secret: config.get('demoSess'),
saveUninitialized: false,
resave: false,
name: 'demo',
cookie: {
maxAge: 60000,
secure: false
},
})
)
const cors = require('cors');
app.use(cors({
origin: [
'http://localhost:4200'
],
credentials: true
})
);
And this how http request is made from frontend:
this.http.get(environment.apiUrl+'/server/page/auth', {withCredentials: true});
Is this how it should be? Backend runs on port 8080 and frontend 4200.
In app.module.ts, I have written TransferHttpCacheModule. If I remove it, I can see from backend, when I console log something, that first http request is made twice- first one doesn't access session and then second one does. So if I was to console.log(req.session.userId) in /server/page/auth, I would get undefined and 1 on next line. As I read, something like this was normal and to get around it, transferstate comes to into play, but as I understand TransferHttpCacheModule is basically easy way to do the transferstate. I tried also with writting the transferstate into resolver and outcomes was same- one request is only made, but that request wont access session.
I am hoping I am missing something when I am making http request from frontend or my session/cors is missing something. At this point I am running out of idea what to check or test, any hint what to check out is welcoming.
So I started to build around my authentication in Angular to use localStorage. I ran there into problem and while searching for solution I ran into tutorial talking something about isPlatformBrowser. So I started thinking, maybe Angular Universal in some way is making two request, but these two request are different and I need to eliminate one of them. So I ended up wrapping my http request with if(isPlatformBrowser(this.platformId)) { } and so far it seems I got my problem fixed.

angular2 & lite server dot in url leads to 404 not found

I'm using Angular2 Beta 14 and calling a URL with a "dot" in it leads to a 404 not found error from the lite server which is 2.2.0.
This is the URL I'm calling:
http://localhost:3000/confirmuser/token/eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjYsInVzZXJOYW1lIjoiYXNkZmFzQGNlZC5saSJ9.PMzNWp8mbUKbSAiOqhOqjhZUYNejXY3pIQueBkc8_2E
The router path in app.component.ts looks like this:
{path: '/confirmuser/token/:token', name: 'ConfirmUser', component: ConfirmUserComponent}
The Chrome console shows this:
Failed to load resource: the server responded with a status of 404 (Not Found)
Ant the Lite Server:
[1] 16.04.13 15:57:13 404 GET /confirmuser/token/eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjYsInVzZXJOYW1lIjoiYXNkZmFzQGNlZC5saSJ9.PMzNWp8mbUKbSAiOqhOqjhZUYNejXY3pIQueBkc8_2E
When ever I call the url without a "dot", the page gets loaded correctly.
My aim here is, to confirm a user sign up. He receives an email with an URL he has to confirm. Using a JWT in this (and other cases) is habit I've been using.
Now I doubt this is an Angular issue, I believe this is a lite server issue.
Anyone experience with this?
Thanks
I found a suitable workaround for this issue.
Basically I'm getting rid of the path parameter ":token" and replacing it by a query parameter
In the app.component.ts the new path now looks like this:
{path: '/confirmuser', name: 'ConfirmUser', component: ConfirmUserComponent}
An the URL like this:
http://localhost:3000/confirmuser?token=eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjYsInVzZXJOYW1lIjoiYXNkZmFzQGNlZC5saSJ9.PMzNWp8mbUKbSAiOqhOqjhZUYNejXY3pIQueBkc8_2E
In the component that handles this request I can continue to call route params as I was used to. So nothing to change there:
constructor(params: RouteParams){
this.token = params.get('token')
...
This question has been answered in https://stackoverflow.com/a/36283859/1465640#
But it can be summarized with dots doesn't work in urls unless you do some work on the lite-server config.
If you are using webpack then you need to change the config to make it working.
Please make the change in webpack dev server config file
historyApiFallback: {
disableDotRule: true
},

Grails Rest Client Builder POST Return Error/Exception

I've been working with the grails plugin: 'grails-rest-client-builder:2.0.1'
https://github.com/grails-plugins/grails-rest-client-builder/
I'm experiencing an odd issue when I POST some data to a web service, a 500 Exception, even though the POST indeed is working successfully.
Class
java.lang.NoClassDefFoundError
Message
org/springframework/util/StreamUtils
Around line 195 of PageFragmentCachingFilter.java
if (CollectionUtils.isEmpty(cacheOperations)) {
log.debug("No cacheable annotation found for {}:{} {}"
new Object[] { request.getMethod(), request.getRequestURI(), getContext() });
chain.doFilter(request, response);
return;
}
The response that is coming back from the web service should look like this:
{"id":"9999","key":"IX-2247","self":"https://jira.xxxx.com/rest/api/latest/issue/9999"}
Again, the web service is correctly getting the values that I pass into it, and I verified this by checking the application that I'm posting to and I do see what I expect. Not only that, but I also receive an email from the system that I am POSTing to, and the email contains the correct values from the Grails application.
Here's the POST that I'm using:
def rest = new grails.plugins.rest.client.RestBuilder()
def resp = rest.post("https://jira.xxxx.com/rest/api/latest/issue/"){
auth "Basic xxxx"
contentType "application/json"
json builder.toPrettyString()
}
My hypothesis is that perhaps the issue is that the rest-client-builder is having some kind of issue with the response that is being returned from the web service.
Has anyone encountered anything like this before, where the service is working, but Grails throws a 500 error, even on a successful POST?
Please let me know if I need to provide additional information.
Thanks in advance!
Thank you all for the replies. I ended up upgrading my Grails application to 2.3.5, from 2.2.3 and now the code (above) works perfectly. The 500 error disappeared completely.

Jquery-upload-progress cross domain issue. Suspected GET request problem

I am doing a site which submits a form to a different server. For upload progress tracking I use: for server side the NginxHttpUploadProgressModule und for client side - jquery-upload-progress. I have tested the setup by submitting the form to the same server and everything worked fine. Submitting to another server doesn't show the progress tracking(cross domain scripting). After hours of investigating this matter I came to the conclusion that the GET request generated by JQuery is at fault.
The query looks like this:
http://domain.com/upload/progress/?X-Progress-ID=39b2825934dbb2f33fe936df734ff840&callback=jsonp1249230337707&_=1249230345572
From the NginxHttpUploadProgressModule site:
The HTTP request to this location must have either an X-Progress-ID parameter or X-Progress-ID HTTP header containing the unique identifier as specified in your upload/POST request to the relevant tracked zone. If you are using the X-Progress-ID as a query-string parameter, ensure it is the LAST argument in the URL.
So, my question is how do I append the X-Progress-ID parameter to the end of the jquery GET request or set the X-Progress-ID header?
This doesn't work with jsonp(code from jquery.uploadProgress.js):
beforeSend: function(xhr) {
xhr.setRequestHeader("X-Progress-ID", options.uuid);
}
Currently the request is generated this way(code from jquery.uploadProgress.js):
jQuery.uploadProgress = function(e, options) {
jQuery.ajax({
type: "GET",
url: options.progressUrl + "?X-Progress-ID=" + options.uuid,
dataType: options.dataType,
success: function(upload) {
...
I solved the GET parameter problem(code from jquery.uploadProgress.js):
jQuery.uploadProgress = function(e, options) {
jQuery.ajax({
type: "GET",
url: options.progressUrl,
dataType: options.dataType,
data: "X-Progress-ID=" + options.uuid,
success: function(upload) {
...
Modified GET request looks like this:
http://domain.com/upload/progress/?callback=jsonp1249230337707&_=1249230345572&X-Progress-ID=39b2825934dbb2f33fe936df734ff840
The nginx webserver is now correctly responding.
However as Ron Evans pointed out the client side progress tracking part won't work unless NginxHttpUploadProgressModule is modified.
You simply cannot fire an XmlHttpRequest from a webpage, to a domain different from the page's domain. It violates security definitions that are default on all browsers.
the only thing that I can think of that you can do is to use Flash or Silverlight to initiate the progress calls (Flash and Silverlight can, given the correct crossdomain.xml setup, send async requests from the browser to preset list of domains)
or, setup a browser addin (say Firefox plugin, or IE ActiveX, or Embedded WinForm control) that can initiate calls without the same-domain restriction (as the request will not originate from the webpage, but from the browser itself)
You need to install the Apache module for upload status as well, just using the jQuery plugin will not work.
To respond to Ken, I suggest you familiarize yourself with JSONP spec, since JSONP was created specifically to handle cross-domain Javascript calls.
Anyhow, this code works great in Passenger/Apache WITH my modified Apache module. Without modifying the extension for Nginx it will not work with a JSONP call.
I made a minor modification that solved the problem for me, you can check it out here:
http://github.com/tizoc/nginx-upload-progress-module/commit/a40b89f63b5a767faec3c78d826443a94dc5b126

Resources