Shopify app with proxy extension POST requests not working - ajax

Following the guide here: https://shopify.dev/tutorials/display-data-on-an-online-store-with-an-application-proxy-app-extension
GET requests are working fine for me.
But when I try to do a POST request, my parameters are not coming through.
I'm building a simple wishlist app, where a user can click on a heart on a product and it adds it to a database.
So my code, when they click the heart, looks something like this:
$.ajax({
url: '/apps/wishlist/save',
type: 'POST',
data: {
shop: shop,
customerId: customerId,
productId: productId
},
dataType: 'json',
success: function (data) {
console.info(data);
}
});
When I inspect this post in Network tab in Chrome Dev Tools, the original POST is hitting a 301, then Shopify is creating a GET request to the original URL with different/missing parameters that look like this:
shop: example.myshopify.com
path_prefix: /apps/wishlist
timestamp: 1585769299
signature: examplesignature
If I change my original AJAX request to a GET, then my original parameters are passed as expected.
Are POST requests not allowed here?

Try to add / to the end of your url i.e. change it to /apps/wishlist/save/.

Just to give a clearification.
Vladimir answer works, why?
It seems that Shopify changed their authentication flow for some POSTs request.
You have to send requests without cookies or you can send requests with X-Shopify-Access-Token header and use your app's password for it. They should work both but there are some cases of use that doesn't permit you to send request without cookie or only uses basic auth (depending on wich method and software you use to send request). Shopify's devs are not crazy of course, this was implemented due to avoid some kind of hackers attack based on specific attacking methods, but maybe it should be better clearly specified in their documentation. Even if the solution explained above should be preferred, as said it could not work in some cases so the Vladimir 's solution is a valid alternative (you could also add a dot at the end of the URL so for example: www.example.com./etc/etc), this because this way "blocks" the cookie seending.
You can know more about that following Sopify's community discussion here

Related

Having trouble making an HTTP request to an API using Bigcommerce

So I'm working on Bigcommerce to build a website for a client. since Bigcommerce does not allow the upload of PHP files on their system I'm using AJAX in a script tag in an HTML file. The documentation for the API I'm using says to use my API key in the username field for HTTP Basic Authentication, and that all requests must be transmitted over HTTPS.
So firstly, here's my code
$.ajax({
type: 'POST',
url : "https://www.freightview.com/api/v1.0/rates",
data : ({ myRequest }),
dataType : "jsonp",
Accept: 'application/json',
beforeSend : function(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + "MyKey:");
}
})
I've tried doing
Username : 'mykey'
and some other various ways to put the key in there but keep getting
401 Unauthroized
I've searched around for some ways to do this and noted a few possible issues:
Ajax GET request over HTTPS
It's mentioned on this page that AJAX cannot make cross-domain HTTPS requests. Does this mean I have to find another way to make the request? If so, how can I make such a request with the limitations I have?
Is it simply that I'm not properly defining my username for the Authentication? I'm hoping this is the only problem, but I've looked at a lot of questions on this site about Basic Auth in AJAX.
JQuery Ajax calls with HTTP Basic Authentication The user who asks this question seems to have a similar problem to mine, but the answers are quite varied, and I'm not sure if they'll work in my situation or even how to begin implementing them. Do I need CORS? Can I even get CORS to work on Bigcommerce?
So as you can see what I thought would be a relatively simple snippet of code turned out to be a lot more complex than I thought, and I could really use some of that StackOverflow magic!
Edit: grammar and spelling
In BigCommerce you have to encode your credentials with Base64.
Example:
// Define the string
var string = 'Hello World!';
// Encode the String
var encodedString = btoa(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
// Decode the String
var decodedString = atob(encodedString);
console.log(decodedString); // Outputs: "Hello World!"

Vimeo CORS Issue

I am trying to upload a video to Vimeo via Ajax but I am running into CORS problems with Firefox.
Here is the code I am using. It is only at the last stage of posting the file does CORS protection prevent the upload.
I have checked the headers and Cross Origin is set correctly.
$.ajax({
url:'https://api.vimeo.com/me',
crossDomain:true,
headers:{Authorization: 'bearer ',Accept:'application/vnd.vimeo.*+json;version=3.2'},
error:function(){
videoError('Couldn\'t get a quota');
},
success:function(uploadQuota){
if(uploadQuota.upload_quota.space.free > 0 && (uploadQuota.upload_quota.quota.sd == true || uploadQuota.upload_quota.quota.hd == true)){
//Get Upload Ticket
$.ajax({
url:'https://api.vimeo.com/me/videos',
data:{type:'POST'},
type:'POST',
dataType:'json',
crossDomain:true,
headers:{Authorization: 'bearer ',Accept:'application/vnd.vimeo.*+json;version=3.2'},
error:function(){
videoError('Couldn\'t get a ticket');
},
success:function(uploadTicket){
if(uploadTicket.ticket_id != ''){
//Upload File
var videoData = new FormData();
$.each($('#video_upload')[0].files, function(i, file) {
videoData.append('file_data', file);
});
$.ajax({
url:uploadTicket.upload_link_secure,
type:'POST',
headers:{Authorization: 'bearer ',Accept:'application/vnd.vimeo.*+json;version=3.2'},
data: videoData,
cache: false,
contentType: 'multipart/form-data',
processData: false,
crossDomain:true,
//dataType:'jsonp',
error:function(){
videoError('Error uploading video. Please contact FDN with the ticket id:'+uploadTicket.ticket_id);
},
success:function(uploadData,status){
//Copy id to text box
}
});
} else {
//If none, process error
}
}
});
} else {
//If none, process error
}
}
});
Is there anything obvious that I have missed or can try?
Short Answer: Vimeo POST uploads were not designed for client side JavaScript. The PUT upload system has 100% support for CORS.
Long Answer:
Vimeo POST uploads were developed to provide an incredibly easy upload experience. We give you a form. You put the form in the html of your page, The user uses the form, and everything is set. This does not support progress bars. This is not resumable.
When uploading videos, we must perform some post-processing before the video will become available. The current POST upload system handles this automatically, by redirecting the client after the upload is complete. Unfortunately there are some problems with CORS and redirects (I'm having trouble finding the details, but if I remember right the spec states to handle certain redirects as an error case).
Right now you must complete the upload yourself. We are working on improving this, but for the moment you have to find the url in the "location" header of the response from your POST. Make a GET request to this url and your upload will be complete.
Vimeo PUT uploads were designed as the fully featured advanced upload system. They are resumable, the streaming design easily supports progress bars. You can query the status of the upload, and start and stop everything on command. CORS is 100% supported. This will require use of the HTML5 file object, which has limited support for ie 9 and lower.
[Edit] There is now an unofficial Client side video upload script for the streaming workflow. You can find it here: https://github.com/websemantics/vimeo-upload
As #Dashron mentioned, the "Simple HTTP POST uploading" should be used for simple cases. For example, if you want to resume an upload you should use the "Resumable HTTP PUT uploads".
However, there are two pieces of information missing on almost all references to similar problems that I would like to share.
1) Be Careful when using vimeo-upload
As #PaulLoomijmans mentioned in a comment to #Dashron the vimeo-upload (github.com/websemantics/vimeo-upload) requires you to expose your token, which is not good for security reasons.
I actually just left a suggestion in the repository that it would still be very useful if we were able to use it with an upload_url from vimeo since then we would not have to expose our token.
2) You can check upload progress using the POST upload method
If like myself, you just want to be able to report to the user the upload progress while using the simplified upload process of the "Simple HTTP POST uploading" you can actually do so without the PUT method.
Even though not clearly documented, when using the "Simple HTTP POST uploading" you also have an "upload_link_secure" in the initial response (https://developer.vimeo.com/api/upload/videos#generate-an-upload-ticket) and you can use this as you would to with the "Resumable HTTP PUT uploads" to check your upload progress.
As such, even when using "Simple HTTP POST uploading" you can follow the information on "verify the upload" from "Resumable HTTP PUT uploads" (here: https://developer.vimeo.com/api/upload/videos#verify-the-upload). Probably the resume functionality described there will not work but you can check the upload progress and show it to the user while the upload is being made. I actually implemented it to show a progress bar in my webapp.
I hope this helps someone, as I went back and forth between the two upload methods due to the limitations/complexity that each entails.

GData API and cross-domain ajax calls

I want to get xml data from google server using it's API. so, i can't make any changes to response. So, How do I make this call that work for me:
$.ajax({
type: 'POST',
url: 'https://www.google.com/accounts/ClientLogin',
contentType: 'application/x-www-form-urlencoded',
data: { accountType : "HOSTED", Email : ""+Adminemail+"", Passwd : ""+adminpass+"", service : "cp"}, // cp for contact service..
success: function (response) {
alert(response); });
I want make some GET, PUT, DELETE call as well so, I don't want to use any function like $.getJSON();I want to make it possible through $.ajax() only.
I think only way to do this is use of server side scripting language.
Most browsers won't allow cross site scripting. (An ajax call that is not in your own domain).
So if you want to call such an url (https://www.google.com/accounts/ClientLogin), do it server side.
Cross domain posting is blocked by the browser. You could write your own browser. Since this is probably not an option, you could post to your own server and from there post to the other server. I think you can post data to another server using cUrl if you're using PHP.
There's a nice example here.
The third party must provide a jsonp api.

post function of jquery

I am running this code :
$.post('https://graph.facebook.com/me',{},
function(msg){
console.log( "Data Saved: " + msg );
}
);
and I am only getting Data Saved : as output in firebug nothig else is coming and call to the url is also not showing why ?
You can't post to another domain (or protocol, or port). More specifically, you can but you can't see the response that comes back for security reasons. This is part of the same origin policy browsers implement to keep your data from being posted/exploited on remote domains that aren't the same as the page you went to.
Picture for example I loaded http://www.yoursite.com and it tried to repeatedly post (as me remember) to https://www.mybank.com, using my stored cookies, etc...you see how you really wouldn't want that to happen...that's why it's disallowed and the response you get back will be null instead of actually seeing the content.
In this case you're looking for one of their API calls using JSONP (callback=? on the URL in jQuery), which works by creating a <script> tag...an entirely different thing altogether. In your case you're looking for something like this:
$.getJSON('https://graph.facebook.com/me?callback=?', function(msg){
console.log(msg);
});
Though, that's not a valid API call by itself (e.g. you need an access token at least), you'll need to use the method you're actually looking for instead.
Bit of a tangent, but since this is so misunderstood, let's take another more popular example to illustrate the dangers if this was allowed. Think about all those services you stay logged into, Facebook, Twitter, etc. This is another facet of the same origin policy, not allowing your cookies, etc to be used is you do try and post...why is this? If my page could just post to Facebook or Twitter already logged in as you, man I could easily broadcast whatever message I wanted...you can see how this would be useful....and immediately used for evil as well.

JQuery .ajax request does not hit the server

I am making an ajax request using JQuery that looks like this:
var data = createXMLdata();
$.ajax({
url: 'http://localhost:8080/foo/bar',
type: "PUT",
data: data,
processData: false,
contentType: "application/text",
error: function(xhr, status, error) {
alert("Error: " + status);
},
success: function() {
alert("Success!");
}
});
When the code executes, I get the success alert, but the service is never executed on the server!
Here's some more data:
If I make the same request using a separate REST client, the service is executed correctly
If I shut down the server (nothing is running) so that hitting that URL gives me a 404, I still get a success message.
I have tried replacing the data with "foo". This works from the REST client, but gives the same result from the code.
Any ideas are greatly appreciated!
The documentation about .ajax()'s type attribute says:
The type of request to make ("POST" or "GET"), default is "GET". Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers.
So probably your browser does not support PUT and the data is sent via POST instead (and therefore not recognized by your service).
Use Firebug or similar to find out which method is used.
One idea to make it working:
Send the data using POST but add an additional field e.g. __http_method=PUT. On the server side, your service has to recognize this and perform the PUT functionality.
This might be not the nicest solution but it is also used by other frameworks I have encountered (e.g. symfony for PHP).
PUT isn't supported by all browsers
Nick Craver made a comment on my question:
Is the page you're running this in served from port 8080?
It turns out this led to me solving the problem. When both the app and the service were hosted on the same server (and port), the problem went away.
This post suggests that if I comment answers the question, and the commenter does not re-post as an answer, I am to post my own answer and accept it. Nick, if you return to post this as an answer, I will accept it over my own.

Resources